aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-01 15:09:04 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-01 15:09:04 -0400
commit2c0c86d5b67ee04e8b71a2ea2a3af6d224611cfc (patch)
tree84cb3b96e68be80b3e8b6876b27fc9ff6ba0370f
parentfdb2f9c2ebd4f07d7b11a3bc86d8c669eb841697 (diff)
parent494bfec99922d54054d2d0873f1017680cfc3f13 (diff)
Merge tag 'clk-for-linus' of git://git.linaro.org/people/mturquette/linux
Pull clk framework update from Michael Turquette: "The common clk framework changes for 3.7 are dominated by ARM platform ports to the framework along with one MIPS port, one MFD port, one minor framework enhancement and one helper function for platforms expressing their clock data through device tree." * tag 'clk-for-linus' of git://git.linaro.org/people/mturquette/linux: clk: add of_clk_src_onecell_get() support clk: ux500: Define smp_twd clock for u8500 mfd: dbx500: Provide a more accurate smp_twd clock clk: ux500: Support for prmcu_rate clock clk: Provide option for clk_get_rate to issue hw for new rate clock: max77686: Add driver for Maxim 77686 32Khz crystal oscillator. ARM: ux500: Switch to use common clock framework clk: ux500: Clock definitions for u8500 clk: ux500: First version of clock definitions for ux500 clk: ux500: Adapt PRCMU and PRCC clocks for common clk clk: versatile: make config option boolean clk: add Loongson1B clock support arm: mmp: make all SOCs use common clock by default clk: mmp: add clock definition for mmp2 clk: mmp: add clock definition for pxa910 clk: mmp: add clock definition for pxa168 clk: mmp: add mmp specific clocks clk: convert ARM RealView to common clk clk: prima2: move from arch/arm/mach to drivers/clk ARM: PRIMA2: convert to common clk and finish full clk tree
-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
-rw-r--r--drivers/clk/Kconfig13
-rw-r--r--drivers/clk/Makefile9
-rw-r--r--drivers/clk/clk-ls1x.c111
-rw-r--r--drivers/clk/clk-max77686.c244
-rw-r--r--drivers/clk/clk-prima2.c1171
-rw-r--r--drivers/clk/clk.c57
-rw-r--r--drivers/clk/mmp/Makefile9
-rw-r--r--drivers/clk/mmp/clk-apbc.c152
-rw-r--r--drivers/clk/mmp/clk-apmu.c97
-rw-r--r--drivers/clk/mmp/clk-frac.c153
-rw-r--r--drivers/clk/mmp/clk-mmp2.c449
-rw-r--r--drivers/clk/mmp/clk-pxa168.c346
-rw-r--r--drivers/clk/mmp/clk-pxa910.c320
-rw-r--r--drivers/clk/mmp/clk.h35
-rw-r--r--drivers/clk/ux500/Makefile12
-rw-r--r--drivers/clk/ux500/clk-prcc.c164
-rw-r--r--drivers/clk/ux500/clk-prcmu.c252
-rw-r--r--drivers/clk/ux500/clk.h48
-rw-r--r--drivers/clk/ux500/u8500_clk.c477
-rw-r--r--drivers/clk/ux500/u8540_clk.c21
-rw-r--r--drivers/clk/ux500/u9540_clk.c21
-rw-r--r--drivers/clk/versatile/Makefile1
-rw-r--r--drivers/clk/versatile/clk-realview.c114
-rw-r--r--drivers/mfd/db8500-prcmu.c42
-rw-r--r--drivers/mfd/dbx500-prcmu-regs.h4
-rw-r--r--include/linux/clk-provider.h6
-rw-r--r--include/linux/mfd/dbx500-prcmu.h1
-rw-r--r--include/linux/platform_data/clk-realview.h1
-rw-r--r--include/linux/platform_data/clk-ux500.h17
47 files changed, 4360 insertions, 1547 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)
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 7f0b5ca78516..bace9e98f75d 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -40,4 +40,17 @@ config COMMON_CLK_WM831X
40 Supports the clocking subsystem of the WM831x/2x series of 40 Supports the clocking subsystem of the WM831x/2x series of
41 PMICs from Wolfson Microlectronics. 41 PMICs from Wolfson Microlectronics.
42 42
43config COMMON_CLK_VERSATILE
44 bool "Clock driver for ARM Reference designs"
45 depends on ARCH_INTEGRATOR || ARCH_REALVIEW
46 ---help---
47 Supports clocking on ARM Reference designs Integrator/AP,
48 Integrator/CP, RealView PB1176, EB, PB11MP and PBX.
49
50config COMMON_CLK_MAX77686
51 tristate "Clock driver for Maxim 77686 MFD"
52 depends on MFD_MAX77686
53 ---help---
54 This driver supports Maxim 77686 crystal oscillator clock.
55
43endmenu 56endmenu
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 72ce247a0e8d..b7b862077d88 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -10,7 +10,14 @@ obj-$(CONFIG_ARCH_MXS) += mxs/
10obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/ 10obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/
11obj-$(CONFIG_PLAT_SPEAR) += spear/ 11obj-$(CONFIG_PLAT_SPEAR) += spear/
12obj-$(CONFIG_ARCH_U300) += clk-u300.o 12obj-$(CONFIG_ARCH_U300) += clk-u300.o
13obj-$(CONFIG_ARCH_INTEGRATOR) += versatile/ 13obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/
14obj-$(CONFIG_ARCH_PRIMA2) += clk-prima2.o
15ifeq ($(CONFIG_COMMON_CLK), y)
16obj-$(CONFIG_ARCH_MMP) += mmp/
17endif
18obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o
19obj-$(CONFIG_ARCH_U8500) += ux500/
14 20
15# Chip specific 21# Chip specific
16obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o 22obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
23obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o
diff --git a/drivers/clk/clk-ls1x.c b/drivers/clk/clk-ls1x.c
new file mode 100644
index 000000000000..f20b750235f6
--- /dev/null
+++ b/drivers/clk/clk-ls1x.c
@@ -0,0 +1,111 @@
1/*
2 * Copyright (c) 2012 Zhang, Keguang <keguang.zhang@gmail.com>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 */
9
10#include <linux/clkdev.h>
11#include <linux/clk-provider.h>
12#include <linux/io.h>
13#include <linux/slab.h>
14#include <linux/err.h>
15
16#include <loongson1.h>
17
18#define OSC 33
19
20static DEFINE_SPINLOCK(_lock);
21
22static int ls1x_pll_clk_enable(struct clk_hw *hw)
23{
24 return 0;
25}
26
27static void ls1x_pll_clk_disable(struct clk_hw *hw)
28{
29}
30
31static unsigned long ls1x_pll_recalc_rate(struct clk_hw *hw,
32 unsigned long parent_rate)
33{
34 u32 pll, rate;
35
36 pll = __raw_readl(LS1X_CLK_PLL_FREQ);
37 rate = ((12 + (pll & 0x3f)) * 1000000) +
38 ((((pll >> 8) & 0x3ff) * 1000000) >> 10);
39 rate *= OSC;
40 rate >>= 1;
41
42 return rate;
43}
44
45static const struct clk_ops ls1x_pll_clk_ops = {
46 .enable = ls1x_pll_clk_enable,
47 .disable = ls1x_pll_clk_disable,
48 .recalc_rate = ls1x_pll_recalc_rate,
49};
50
51static struct clk * __init clk_register_pll(struct device *dev,
52 const char *name, const char *parent_name, unsigned long flags)
53{
54 struct clk_hw *hw;
55 struct clk *clk;
56 struct clk_init_data init;
57
58 /* allocate the divider */
59 hw = kzalloc(sizeof(struct clk_hw), GFP_KERNEL);
60 if (!hw) {
61 pr_err("%s: could not allocate clk_hw\n", __func__);
62 return ERR_PTR(-ENOMEM);
63 }
64
65 init.name = name;
66 init.ops = &ls1x_pll_clk_ops;
67 init.flags = flags | CLK_IS_BASIC;
68 init.parent_names = (parent_name ? &parent_name : NULL);
69 init.num_parents = (parent_name ? 1 : 0);
70 hw->init = &init;
71
72 /* register the clock */
73 clk = clk_register(dev, hw);
74
75 if (IS_ERR(clk))
76 kfree(hw);
77
78 return clk;
79}
80
81void __init ls1x_clk_init(void)
82{
83 struct clk *clk;
84
85 clk = clk_register_pll(NULL, "pll_clk", NULL, CLK_IS_ROOT);
86 clk_prepare_enable(clk);
87
88 clk = clk_register_divider(NULL, "cpu_clk", "pll_clk",
89 CLK_SET_RATE_PARENT, LS1X_CLK_PLL_DIV, DIV_CPU_SHIFT,
90 DIV_CPU_WIDTH, CLK_DIVIDER_ONE_BASED, &_lock);
91 clk_prepare_enable(clk);
92 clk_register_clkdev(clk, "cpu", NULL);
93
94 clk = clk_register_divider(NULL, "dc_clk", "pll_clk",
95 CLK_SET_RATE_PARENT, LS1X_CLK_PLL_DIV, DIV_DC_SHIFT,
96 DIV_DC_WIDTH, CLK_DIVIDER_ONE_BASED, &_lock);
97 clk_prepare_enable(clk);
98 clk_register_clkdev(clk, "dc", NULL);
99
100 clk = clk_register_divider(NULL, "ahb_clk", "pll_clk",
101 CLK_SET_RATE_PARENT, LS1X_CLK_PLL_DIV, DIV_DDR_SHIFT,
102 DIV_DDR_WIDTH, CLK_DIVIDER_ONE_BASED, &_lock);
103 clk_prepare_enable(clk);
104 clk_register_clkdev(clk, "ahb", NULL);
105 clk_register_clkdev(clk, "stmmaceth", NULL);
106
107 clk = clk_register_fixed_factor(NULL, "apb_clk", "ahb_clk", 0, 1, 2);
108 clk_prepare_enable(clk);
109 clk_register_clkdev(clk, "apb", NULL);
110 clk_register_clkdev(clk, "serial8250", NULL);
111}
diff --git a/drivers/clk/clk-max77686.c b/drivers/clk/clk-max77686.c
new file mode 100644
index 000000000000..ac5f5434cb9a
--- /dev/null
+++ b/drivers/clk/clk-max77686.c
@@ -0,0 +1,244 @@
1/*
2 * clk-max77686.c - Clock driver for Maxim 77686
3 *
4 * Copyright (C) 2012 Samsung Electornics
5 * Jonghwa Lee <jonghwa3.lee@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#include <linux/kernel.h>
24#include <linux/slab.h>
25#include <linux/err.h>
26#include <linux/platform_device.h>
27#include <linux/mfd/max77686.h>
28#include <linux/mfd/max77686-private.h>
29#include <linux/clk-provider.h>
30#include <linux/mutex.h>
31#include <linux/clkdev.h>
32
33enum {
34 MAX77686_CLK_AP = 0,
35 MAX77686_CLK_CP,
36 MAX77686_CLK_PMIC,
37 MAX77686_CLKS_NUM,
38};
39
40struct max77686_clk {
41 struct max77686_dev *iodev;
42 u32 mask;
43 struct clk_hw hw;
44 struct clk_lookup *lookup;
45};
46
47static struct max77686_clk *get_max77686_clk(struct clk_hw *hw)
48{
49 return container_of(hw, struct max77686_clk, hw);
50}
51
52static int max77686_clk_prepare(struct clk_hw *hw)
53{
54 struct max77686_clk *max77686;
55 int ret;
56
57 max77686 = get_max77686_clk(hw);
58 if (!max77686)
59 return -ENOMEM;
60
61 ret = regmap_update_bits(max77686->iodev->regmap,
62 MAX77686_REG_32KHZ, max77686->mask, max77686->mask);
63
64 return ret;
65}
66
67static void max77686_clk_unprepare(struct clk_hw *hw)
68{
69 struct max77686_clk *max77686;
70
71 max77686 = get_max77686_clk(hw);
72 if (!max77686)
73 return;
74
75 regmap_update_bits(max77686->iodev->regmap,
76 MAX77686_REG_32KHZ, max77686->mask, ~max77686->mask);
77}
78
79static int max77686_clk_is_enabled(struct clk_hw *hw)
80{
81 struct max77686_clk *max77686;
82 int ret;
83 u32 val;
84
85 max77686 = get_max77686_clk(hw);
86 if (!max77686)
87 return -ENOMEM;
88
89 ret = regmap_read(max77686->iodev->regmap,
90 MAX77686_REG_32KHZ, &val);
91
92 if (ret < 0)
93 return -EINVAL;
94
95 return val & max77686->mask;
96}
97
98static struct clk_ops max77686_clk_ops = {
99 .prepare = max77686_clk_prepare,
100 .unprepare = max77686_clk_unprepare,
101 .is_enabled = max77686_clk_is_enabled,
102};
103
104static struct clk_init_data max77686_clks_init[MAX77686_CLKS_NUM] = {
105 [MAX77686_CLK_AP] = {
106 .name = "32khz_ap",
107 .ops = &max77686_clk_ops,
108 .flags = CLK_IS_ROOT,
109 },
110 [MAX77686_CLK_CP] = {
111 .name = "32khz_cp",
112 .ops = &max77686_clk_ops,
113 .flags = CLK_IS_ROOT,
114 },
115 [MAX77686_CLK_PMIC] = {
116 .name = "32khz_pmic",
117 .ops = &max77686_clk_ops,
118 .flags = CLK_IS_ROOT,
119 },
120};
121
122static int max77686_clk_register(struct device *dev,
123 struct max77686_clk *max77686)
124{
125 struct clk *clk;
126 struct clk_hw *hw = &max77686->hw;
127
128 clk = clk_register(dev, hw);
129
130 if (IS_ERR(clk))
131 return -ENOMEM;
132
133 max77686->lookup = devm_kzalloc(dev, sizeof(struct clk_lookup),
134 GFP_KERNEL);
135 if (IS_ERR(max77686->lookup))
136 return -ENOMEM;
137
138 max77686->lookup->con_id = hw->init->name;
139 max77686->lookup->clk = clk;
140
141 clkdev_add(max77686->lookup);
142
143 return 0;
144}
145
146static __devinit int max77686_clk_probe(struct platform_device *pdev)
147{
148 struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent);
149 struct max77686_clk **max77686_clks;
150 int i, ret;
151
152 max77686_clks = devm_kzalloc(&pdev->dev, sizeof(struct max77686_clk *)
153 * MAX77686_CLKS_NUM, GFP_KERNEL);
154 if (IS_ERR(max77686_clks))
155 return -ENOMEM;
156
157 for (i = 0; i < MAX77686_CLKS_NUM; i++) {
158 max77686_clks[i] = devm_kzalloc(&pdev->dev,
159 sizeof(struct max77686_clk), GFP_KERNEL);
160 if (IS_ERR(max77686_clks[i]))
161 return -ENOMEM;
162 }
163
164 for (i = 0; i < MAX77686_CLKS_NUM; i++) {
165 max77686_clks[i]->iodev = iodev;
166 max77686_clks[i]->mask = 1 << i;
167 max77686_clks[i]->hw.init = &max77686_clks_init[i];
168
169 ret = max77686_clk_register(&pdev->dev, max77686_clks[i]);
170 if (ret) {
171 switch (i) {
172 case MAX77686_CLK_AP:
173 dev_err(&pdev->dev, "Fail to register CLK_AP\n");
174 goto err_clk_ap;
175 break;
176 case MAX77686_CLK_CP:
177 dev_err(&pdev->dev, "Fail to register CLK_CP\n");
178 goto err_clk_cp;
179 break;
180 case MAX77686_CLK_PMIC:
181 dev_err(&pdev->dev, "Fail to register CLK_PMIC\n");
182 goto err_clk_pmic;
183 }
184 }
185 }
186
187 platform_set_drvdata(pdev, max77686_clks);
188
189 goto out;
190
191err_clk_pmic:
192 clkdev_drop(max77686_clks[MAX77686_CLK_CP]->lookup);
193 kfree(max77686_clks[MAX77686_CLK_CP]->hw.clk);
194err_clk_cp:
195 clkdev_drop(max77686_clks[MAX77686_CLK_AP]->lookup);
196 kfree(max77686_clks[MAX77686_CLK_AP]->hw.clk);
197err_clk_ap:
198out:
199 return ret;
200}
201
202static int __devexit max77686_clk_remove(struct platform_device *pdev)
203{
204 struct max77686_clk **max77686_clks = platform_get_drvdata(pdev);
205 int i;
206
207 for (i = 0; i < MAX77686_CLKS_NUM; i++) {
208 clkdev_drop(max77686_clks[i]->lookup);
209 kfree(max77686_clks[i]->hw.clk);
210 }
211 return 0;
212}
213
214static const struct platform_device_id max77686_clk_id[] = {
215 { "max77686-clk", 0},
216 { },
217};
218MODULE_DEVICE_TABLE(platform, max77686_clk_id);
219
220static struct platform_driver max77686_clk_driver = {
221 .driver = {
222 .name = "max77686-clk",
223 .owner = THIS_MODULE,
224 },
225 .probe = max77686_clk_probe,
226 .remove = __devexit_p(max77686_clk_remove),
227 .id_table = max77686_clk_id,
228};
229
230static int __init max77686_clk_init(void)
231{
232 return platform_driver_register(&max77686_clk_driver);
233}
234subsys_initcall(max77686_clk_init);
235
236static void __init max77686_clk_cleanup(void)
237{
238 platform_driver_unregister(&max77686_clk_driver);
239}
240module_exit(max77686_clk_cleanup);
241
242MODULE_DESCRIPTION("MAXIM 77686 Clock Driver");
243MODULE_AUTHOR("Jonghwa Lee <jonghwa3.lee@samsung.com>");
244MODULE_LICENSE("GPL");
diff --git a/drivers/clk/clk-prima2.c b/drivers/clk/clk-prima2.c
new file mode 100644
index 000000000000..517874fa6858
--- /dev/null
+++ b/drivers/clk/clk-prima2.c
@@ -0,0 +1,1171 @@
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/io.h>
12#include <linux/clk.h>
13#include <linux/clkdev.h>
14#include <linux/clk-provider.h>
15#include <linux/of_address.h>
16#include <linux/syscore_ops.h>
17
18#define SIRFSOC_CLKC_CLK_EN0 0x0000
19#define SIRFSOC_CLKC_CLK_EN1 0x0004
20#define SIRFSOC_CLKC_REF_CFG 0x0014
21#define SIRFSOC_CLKC_CPU_CFG 0x0018
22#define SIRFSOC_CLKC_MEM_CFG 0x001c
23#define SIRFSOC_CLKC_SYS_CFG 0x0020
24#define SIRFSOC_CLKC_IO_CFG 0x0024
25#define SIRFSOC_CLKC_DSP_CFG 0x0028
26#define SIRFSOC_CLKC_GFX_CFG 0x002c
27#define SIRFSOC_CLKC_MM_CFG 0x0030
28#define SIRFSOC_CLKC_LCD_CFG 0x0034
29#define SIRFSOC_CLKC_MMC_CFG 0x0038
30#define SIRFSOC_CLKC_PLL1_CFG0 0x0040
31#define SIRFSOC_CLKC_PLL2_CFG0 0x0044
32#define SIRFSOC_CLKC_PLL3_CFG0 0x0048
33#define SIRFSOC_CLKC_PLL1_CFG1 0x004c
34#define SIRFSOC_CLKC_PLL2_CFG1 0x0050
35#define SIRFSOC_CLKC_PLL3_CFG1 0x0054
36#define SIRFSOC_CLKC_PLL1_CFG2 0x0058
37#define SIRFSOC_CLKC_PLL2_CFG2 0x005c
38#define SIRFSOC_CLKC_PLL3_CFG2 0x0060
39#define SIRFSOC_USBPHY_PLL_CTRL 0x0008
40#define SIRFSOC_USBPHY_PLL_POWERDOWN BIT(1)
41#define SIRFSOC_USBPHY_PLL_BYPASS BIT(2)
42#define SIRFSOC_USBPHY_PLL_LOCK BIT(3)
43
44static void *sirfsoc_clk_vbase, *sirfsoc_rsc_vbase;
45
46#define KHZ 1000
47#define MHZ (KHZ * KHZ)
48
49/*
50 * SiRFprimaII clock controller
51 * - 2 oscillators: osc-26MHz, rtc-32.768KHz
52 * - 3 standard configurable plls: pll1, pll2 & pll3
53 * - 2 exclusive plls: usb phy pll and sata phy pll
54 * - 8 clock domains: cpu/cpudiv, mem/memdiv, sys/io, dsp, graphic, multimedia,
55 * display and sdphy.
56 * Each clock domain can select its own clock source from five clock sources,
57 * X_XIN, X_XINW, PLL1, PLL2 and PLL3. The domain clock is used as the source
58 * clock of the group clock.
59 * - dsp domain: gps, mf
60 * - io domain: dmac, nand, audio, uart, i2c, spi, usp, pwm, pulse
61 * - sys domain: security
62 */
63
64struct clk_pll {
65 struct clk_hw hw;
66 unsigned short regofs; /* register offset */
67};
68
69#define to_pllclk(_hw) container_of(_hw, struct clk_pll, hw)
70
71struct clk_dmn {
72 struct clk_hw hw;
73 signed char enable_bit; /* enable bit: 0 ~ 63 */
74 unsigned short regofs; /* register offset */
75};
76
77#define to_dmnclk(_hw) container_of(_hw, struct clk_dmn, hw)
78
79struct clk_std {
80 struct clk_hw hw;
81 signed char enable_bit; /* enable bit: 0 ~ 63 */
82};
83
84#define to_stdclk(_hw) container_of(_hw, struct clk_std, hw)
85
86static int std_clk_is_enabled(struct clk_hw *hw);
87static int std_clk_enable(struct clk_hw *hw);
88static void std_clk_disable(struct clk_hw *hw);
89
90static inline unsigned long clkc_readl(unsigned reg)
91{
92 return readl(sirfsoc_clk_vbase + reg);
93}
94
95static inline void clkc_writel(u32 val, unsigned reg)
96{
97 writel(val, sirfsoc_clk_vbase + reg);
98}
99
100/*
101 * std pll
102 */
103
104static unsigned long pll_clk_recalc_rate(struct clk_hw *hw,
105 unsigned long parent_rate)
106{
107 unsigned long fin = parent_rate;
108 struct clk_pll *clk = to_pllclk(hw);
109 u32 regcfg2 = clk->regofs + SIRFSOC_CLKC_PLL1_CFG2 -
110 SIRFSOC_CLKC_PLL1_CFG0;
111
112 if (clkc_readl(regcfg2) & BIT(2)) {
113 /* pll bypass mode */
114 return fin;
115 } else {
116 /* fout = fin * nf / nr / od */
117 u32 cfg0 = clkc_readl(clk->regofs);
118 u32 nf = (cfg0 & (BIT(13) - 1)) + 1;
119 u32 nr = ((cfg0 >> 13) & (BIT(6) - 1)) + 1;
120 u32 od = ((cfg0 >> 19) & (BIT(4) - 1)) + 1;
121 WARN_ON(fin % MHZ);
122 return fin / MHZ * nf / nr / od * MHZ;
123 }
124}
125
126static long pll_clk_round_rate(struct clk_hw *hw, unsigned long rate,
127 unsigned long *parent_rate)
128{
129 unsigned long fin, nf, nr, od;
130
131 /*
132 * fout = fin * nf / (nr * od);
133 * set od = 1, nr = fin/MHz, so fout = nf * MHz
134 */
135 rate = rate - rate % MHZ;
136
137 nf = rate / MHZ;
138 if (nf > BIT(13))
139 nf = BIT(13);
140 if (nf < 1)
141 nf = 1;
142
143 fin = *parent_rate;
144
145 nr = fin / MHZ;
146 if (nr > BIT(6))
147 nr = BIT(6);
148 od = 1;
149
150 return fin * nf / (nr * od);
151}
152
153static int pll_clk_set_rate(struct clk_hw *hw, unsigned long rate,
154 unsigned long parent_rate)
155{
156 struct clk_pll *clk = to_pllclk(hw);
157 unsigned long fin, nf, nr, od, reg;
158
159 /*
160 * fout = fin * nf / (nr * od);
161 * set od = 1, nr = fin/MHz, so fout = nf * MHz
162 */
163
164 nf = rate / MHZ;
165 if (unlikely((rate % MHZ) || nf > BIT(13) || nf < 1))
166 return -EINVAL;
167
168 fin = parent_rate;
169 BUG_ON(fin < MHZ);
170
171 nr = fin / MHZ;
172 BUG_ON((fin % MHZ) || nr > BIT(6));
173
174 od = 1;
175
176 reg = (nf - 1) | ((nr - 1) << 13) | ((od - 1) << 19);
177 clkc_writel(reg, clk->regofs);
178
179 reg = clk->regofs + SIRFSOC_CLKC_PLL1_CFG1 - SIRFSOC_CLKC_PLL1_CFG0;
180 clkc_writel((nf >> 1) - 1, reg);
181
182 reg = clk->regofs + SIRFSOC_CLKC_PLL1_CFG2 - SIRFSOC_CLKC_PLL1_CFG0;
183 while (!(clkc_readl(reg) & BIT(6)))
184 cpu_relax();
185
186 return 0;
187}
188
189static struct clk_ops std_pll_ops = {
190 .recalc_rate = pll_clk_recalc_rate,
191 .round_rate = pll_clk_round_rate,
192 .set_rate = pll_clk_set_rate,
193};
194
195static const char *pll_clk_parents[] = {
196 "osc",
197};
198
199static struct clk_init_data clk_pll1_init = {
200 .name = "pll1",
201 .ops = &std_pll_ops,
202 .parent_names = pll_clk_parents,
203 .num_parents = ARRAY_SIZE(pll_clk_parents),
204};
205
206static struct clk_init_data clk_pll2_init = {
207 .name = "pll2",
208 .ops = &std_pll_ops,
209 .parent_names = pll_clk_parents,
210 .num_parents = ARRAY_SIZE(pll_clk_parents),
211};
212
213static struct clk_init_data clk_pll3_init = {
214 .name = "pll3",
215 .ops = &std_pll_ops,
216 .parent_names = pll_clk_parents,
217 .num_parents = ARRAY_SIZE(pll_clk_parents),
218};
219
220static struct clk_pll clk_pll1 = {
221 .regofs = SIRFSOC_CLKC_PLL1_CFG0,
222 .hw = {
223 .init = &clk_pll1_init,
224 },
225};
226
227static struct clk_pll clk_pll2 = {
228 .regofs = SIRFSOC_CLKC_PLL2_CFG0,
229 .hw = {
230 .init = &clk_pll2_init,
231 },
232};
233
234static struct clk_pll clk_pll3 = {
235 .regofs = SIRFSOC_CLKC_PLL3_CFG0,
236 .hw = {
237 .init = &clk_pll3_init,
238 },
239};
240
241/*
242 * usb uses specified pll
243 */
244
245static int usb_pll_clk_enable(struct clk_hw *hw)
246{
247 u32 reg = readl(sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL);
248 reg &= ~(SIRFSOC_USBPHY_PLL_POWERDOWN | SIRFSOC_USBPHY_PLL_BYPASS);
249 writel(reg, sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL);
250 while (!(readl(sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL) &
251 SIRFSOC_USBPHY_PLL_LOCK))
252 cpu_relax();
253
254 return 0;
255}
256
257static void usb_pll_clk_disable(struct clk_hw *clk)
258{
259 u32 reg = readl(sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL);
260 reg |= (SIRFSOC_USBPHY_PLL_POWERDOWN | SIRFSOC_USBPHY_PLL_BYPASS);
261 writel(reg, sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL);
262}
263
264static unsigned long usb_pll_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
265{
266 u32 reg = readl(sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL);
267 return (reg & SIRFSOC_USBPHY_PLL_BYPASS) ? parent_rate : 48*MHZ;
268}
269
270static struct clk_ops usb_pll_ops = {
271 .enable = usb_pll_clk_enable,
272 .disable = usb_pll_clk_disable,
273 .recalc_rate = usb_pll_clk_recalc_rate,
274};
275
276static struct clk_init_data clk_usb_pll_init = {
277 .name = "usb_pll",
278 .ops = &usb_pll_ops,
279 .parent_names = pll_clk_parents,
280 .num_parents = ARRAY_SIZE(pll_clk_parents),
281};
282
283static struct clk_hw usb_pll_clk_hw = {
284 .init = &clk_usb_pll_init,
285};
286
287/*
288 * clock domains - cpu, mem, sys/io, dsp, gfx
289 */
290
291static const char *dmn_clk_parents[] = {
292 "rtc",
293 "osc",
294 "pll1",
295 "pll2",
296 "pll3",
297};
298
299static u8 dmn_clk_get_parent(struct clk_hw *hw)
300{
301 struct clk_dmn *clk = to_dmnclk(hw);
302 u32 cfg = clkc_readl(clk->regofs);
303
304 /* parent of io domain can only be pll3 */
305 if (strcmp(hw->init->name, "io") == 0)
306 return 4;
307
308 WARN_ON((cfg & (BIT(3) - 1)) > 4);
309
310 return cfg & (BIT(3) - 1);
311}
312
313static int dmn_clk_set_parent(struct clk_hw *hw, u8 parent)
314{
315 struct clk_dmn *clk = to_dmnclk(hw);
316 u32 cfg = clkc_readl(clk->regofs);
317
318 /* parent of io domain can only be pll3 */
319 if (strcmp(hw->init->name, "io") == 0)
320 return -EINVAL;
321
322 cfg &= ~(BIT(3) - 1);
323 clkc_writel(cfg | parent, clk->regofs);
324 /* BIT(3) - switching status: 1 - busy, 0 - done */
325 while (clkc_readl(clk->regofs) & BIT(3))
326 cpu_relax();
327
328 return 0;
329}
330
331static unsigned long dmn_clk_recalc_rate(struct clk_hw *hw,
332 unsigned long parent_rate)
333
334{
335 unsigned long fin = parent_rate;
336 struct clk_dmn *clk = to_dmnclk(hw);
337
338 u32 cfg = clkc_readl(clk->regofs);
339
340 if (cfg & BIT(24)) {
341 /* fcd bypass mode */
342 return fin;
343 } else {
344 /*
345 * wait count: bit[19:16], hold count: bit[23:20]
346 */
347 u32 wait = (cfg >> 16) & (BIT(4) - 1);
348 u32 hold = (cfg >> 20) & (BIT(4) - 1);
349
350 return fin / (wait + hold + 2);
351 }
352}
353
354static long dmn_clk_round_rate(struct clk_hw *hw, unsigned long rate,
355 unsigned long *parent_rate)
356{
357 unsigned long fin;
358 unsigned ratio, wait, hold;
359 unsigned bits = (strcmp(hw->init->name, "mem") == 0) ? 3 : 4;
360
361 fin = *parent_rate;
362 ratio = fin / rate;
363
364 if (ratio < 2)
365 ratio = 2;
366 if (ratio > BIT(bits + 1))
367 ratio = BIT(bits + 1);
368
369 wait = (ratio >> 1) - 1;
370 hold = ratio - wait - 2;
371
372 return fin / (wait + hold + 2);
373}
374
375static int dmn_clk_set_rate(struct clk_hw *hw, unsigned long rate,
376 unsigned long parent_rate)
377{
378 struct clk_dmn *clk = to_dmnclk(hw);
379 unsigned long fin;
380 unsigned ratio, wait, hold, reg;
381 unsigned bits = (strcmp(hw->init->name, "mem") == 0) ? 3 : 4;
382
383 fin = parent_rate;
384 ratio = fin / rate;
385
386 if (unlikely(ratio < 2 || ratio > BIT(bits + 1)))
387 return -EINVAL;
388
389 WARN_ON(fin % rate);
390
391 wait = (ratio >> 1) - 1;
392 hold = ratio - wait - 2;
393
394 reg = clkc_readl(clk->regofs);
395 reg &= ~(((BIT(bits) - 1) << 16) | ((BIT(bits) - 1) << 20));
396 reg |= (wait << 16) | (hold << 20) | BIT(25);
397 clkc_writel(reg, clk->regofs);
398
399 /* waiting FCD been effective */
400 while (clkc_readl(clk->regofs) & BIT(25))
401 cpu_relax();
402
403 return 0;
404}
405
406static struct clk_ops msi_ops = {
407 .set_rate = dmn_clk_set_rate,
408 .round_rate = dmn_clk_round_rate,
409 .recalc_rate = dmn_clk_recalc_rate,
410 .set_parent = dmn_clk_set_parent,
411 .get_parent = dmn_clk_get_parent,
412};
413
414static struct clk_init_data clk_mem_init = {
415 .name = "mem",
416 .ops = &msi_ops,
417 .parent_names = dmn_clk_parents,
418 .num_parents = ARRAY_SIZE(dmn_clk_parents),
419};
420
421static struct clk_dmn clk_mem = {
422 .regofs = SIRFSOC_CLKC_MEM_CFG,
423 .hw = {
424 .init = &clk_mem_init,
425 },
426};
427
428static struct clk_init_data clk_sys_init = {
429 .name = "sys",
430 .ops = &msi_ops,
431 .parent_names = dmn_clk_parents,
432 .num_parents = ARRAY_SIZE(dmn_clk_parents),
433 .flags = CLK_SET_RATE_GATE,
434};
435
436static struct clk_dmn clk_sys = {
437 .regofs = SIRFSOC_CLKC_SYS_CFG,
438 .hw = {
439 .init = &clk_sys_init,
440 },
441};
442
443static struct clk_init_data clk_io_init = {
444 .name = "io",
445 .ops = &msi_ops,
446 .parent_names = dmn_clk_parents,
447 .num_parents = ARRAY_SIZE(dmn_clk_parents),
448};
449
450static struct clk_dmn clk_io = {
451 .regofs = SIRFSOC_CLKC_IO_CFG,
452 .hw = {
453 .init = &clk_io_init,
454 },
455};
456
457static struct clk_ops cpu_ops = {
458 .set_parent = dmn_clk_set_parent,
459 .get_parent = dmn_clk_get_parent,
460};
461
462static struct clk_init_data clk_cpu_init = {
463 .name = "cpu",
464 .ops = &cpu_ops,
465 .parent_names = dmn_clk_parents,
466 .num_parents = ARRAY_SIZE(dmn_clk_parents),
467 .flags = CLK_SET_RATE_PARENT,
468};
469
470static struct clk_dmn clk_cpu = {
471 .regofs = SIRFSOC_CLKC_CPU_CFG,
472 .hw = {
473 .init = &clk_cpu_init,
474 },
475};
476
477static struct clk_ops dmn_ops = {
478 .is_enabled = std_clk_is_enabled,
479 .enable = std_clk_enable,
480 .disable = std_clk_disable,
481 .set_rate = dmn_clk_set_rate,
482 .round_rate = dmn_clk_round_rate,
483 .recalc_rate = dmn_clk_recalc_rate,
484 .set_parent = dmn_clk_set_parent,
485 .get_parent = dmn_clk_get_parent,
486};
487
488/* dsp, gfx, mm, lcd and vpp domain */
489
490static struct clk_init_data clk_dsp_init = {
491 .name = "dsp",
492 .ops = &dmn_ops,
493 .parent_names = dmn_clk_parents,
494 .num_parents = ARRAY_SIZE(dmn_clk_parents),
495};
496
497static struct clk_dmn clk_dsp = {
498 .regofs = SIRFSOC_CLKC_DSP_CFG,
499 .enable_bit = 0,
500 .hw = {
501 .init = &clk_dsp_init,
502 },
503};
504
505static struct clk_init_data clk_gfx_init = {
506 .name = "gfx",
507 .ops = &dmn_ops,
508 .parent_names = dmn_clk_parents,
509 .num_parents = ARRAY_SIZE(dmn_clk_parents),
510};
511
512static struct clk_dmn clk_gfx = {
513 .regofs = SIRFSOC_CLKC_GFX_CFG,
514 .enable_bit = 8,
515 .hw = {
516 .init = &clk_gfx_init,
517 },
518};
519
520static struct clk_init_data clk_mm_init = {
521 .name = "mm",
522 .ops = &dmn_ops,
523 .parent_names = dmn_clk_parents,
524 .num_parents = ARRAY_SIZE(dmn_clk_parents),
525};
526
527static struct clk_dmn clk_mm = {
528 .regofs = SIRFSOC_CLKC_MM_CFG,
529 .enable_bit = 9,
530 .hw = {
531 .init = &clk_mm_init,
532 },
533};
534
535static struct clk_init_data clk_lcd_init = {
536 .name = "lcd",
537 .ops = &dmn_ops,
538 .parent_names = dmn_clk_parents,
539 .num_parents = ARRAY_SIZE(dmn_clk_parents),
540};
541
542static struct clk_dmn clk_lcd = {
543 .regofs = SIRFSOC_CLKC_LCD_CFG,
544 .enable_bit = 10,
545 .hw = {
546 .init = &clk_lcd_init,
547 },
548};
549
550static struct clk_init_data clk_vpp_init = {
551 .name = "vpp",
552 .ops = &dmn_ops,
553 .parent_names = dmn_clk_parents,
554 .num_parents = ARRAY_SIZE(dmn_clk_parents),
555};
556
557static struct clk_dmn clk_vpp = {
558 .regofs = SIRFSOC_CLKC_LCD_CFG,
559 .enable_bit = 11,
560 .hw = {
561 .init = &clk_vpp_init,
562 },
563};
564
565static struct clk_init_data clk_mmc01_init = {
566 .name = "mmc01",
567 .ops = &dmn_ops,
568 .parent_names = dmn_clk_parents,
569 .num_parents = ARRAY_SIZE(dmn_clk_parents),
570};
571
572static struct clk_dmn clk_mmc01 = {
573 .regofs = SIRFSOC_CLKC_MMC_CFG,
574 .enable_bit = 59,
575 .hw = {
576 .init = &clk_mmc01_init,
577 },
578};
579
580static struct clk_init_data clk_mmc23_init = {
581 .name = "mmc23",
582 .ops = &dmn_ops,
583 .parent_names = dmn_clk_parents,
584 .num_parents = ARRAY_SIZE(dmn_clk_parents),
585};
586
587static struct clk_dmn clk_mmc23 = {
588 .regofs = SIRFSOC_CLKC_MMC_CFG,
589 .enable_bit = 60,
590 .hw = {
591 .init = &clk_mmc23_init,
592 },
593};
594
595static struct clk_init_data clk_mmc45_init = {
596 .name = "mmc45",
597 .ops = &dmn_ops,
598 .parent_names = dmn_clk_parents,
599 .num_parents = ARRAY_SIZE(dmn_clk_parents),
600};
601
602static struct clk_dmn clk_mmc45 = {
603 .regofs = SIRFSOC_CLKC_MMC_CFG,
604 .enable_bit = 61,
605 .hw = {
606 .init = &clk_mmc45_init,
607 },
608};
609
610/*
611 * peripheral controllers in io domain
612 */
613
614static int std_clk_is_enabled(struct clk_hw *hw)
615{
616 u32 reg;
617 int bit;
618 struct clk_std *clk = to_stdclk(hw);
619
620 bit = clk->enable_bit % 32;
621 reg = clk->enable_bit / 32;
622 reg = SIRFSOC_CLKC_CLK_EN0 + reg * sizeof(reg);
623
624 return !!(clkc_readl(reg) & BIT(bit));
625}
626
627static int std_clk_enable(struct clk_hw *hw)
628{
629 u32 val, reg;
630 int bit;
631 struct clk_std *clk = to_stdclk(hw);
632
633 BUG_ON(clk->enable_bit < 0 || clk->enable_bit > 63);
634
635 bit = clk->enable_bit % 32;
636 reg = clk->enable_bit / 32;
637 reg = SIRFSOC_CLKC_CLK_EN0 + reg * sizeof(reg);
638
639 val = clkc_readl(reg) | BIT(bit);
640 clkc_writel(val, reg);
641 return 0;
642}
643
644static void std_clk_disable(struct clk_hw *hw)
645{
646 u32 val, reg;
647 int bit;
648 struct clk_std *clk = to_stdclk(hw);
649
650 BUG_ON(clk->enable_bit < 0 || clk->enable_bit > 63);
651
652 bit = clk->enable_bit % 32;
653 reg = clk->enable_bit / 32;
654 reg = SIRFSOC_CLKC_CLK_EN0 + reg * sizeof(reg);
655
656 val = clkc_readl(reg) & ~BIT(bit);
657 clkc_writel(val, reg);
658}
659
660static const char *std_clk_io_parents[] = {
661 "io",
662};
663
664static struct clk_ops ios_ops = {
665 .is_enabled = std_clk_is_enabled,
666 .enable = std_clk_enable,
667 .disable = std_clk_disable,
668};
669
670static struct clk_init_data clk_dmac0_init = {
671 .name = "dmac0",
672 .ops = &ios_ops,
673 .parent_names = std_clk_io_parents,
674 .num_parents = ARRAY_SIZE(std_clk_io_parents),
675};
676
677static struct clk_std clk_dmac0 = {
678 .enable_bit = 32,
679 .hw = {
680 .init = &clk_dmac0_init,
681 },
682};
683
684static struct clk_init_data clk_dmac1_init = {
685 .name = "dmac1",
686 .ops = &ios_ops,
687 .parent_names = std_clk_io_parents,
688 .num_parents = ARRAY_SIZE(std_clk_io_parents),
689};
690
691static struct clk_std clk_dmac1 = {
692 .enable_bit = 33,
693 .hw = {
694 .init = &clk_dmac1_init,
695 },
696};
697
698static struct clk_init_data clk_nand_init = {
699 .name = "nand",
700 .ops = &ios_ops,
701 .parent_names = std_clk_io_parents,
702 .num_parents = ARRAY_SIZE(std_clk_io_parents),
703};
704
705static struct clk_std clk_nand = {
706 .enable_bit = 34,
707 .hw = {
708 .init = &clk_nand_init,
709 },
710};
711
712static struct clk_init_data clk_audio_init = {
713 .name = "audio",
714 .ops = &ios_ops,
715 .parent_names = std_clk_io_parents,
716 .num_parents = ARRAY_SIZE(std_clk_io_parents),
717};
718
719static struct clk_std clk_audio = {
720 .enable_bit = 35,
721 .hw = {
722 .init = &clk_audio_init,
723 },
724};
725
726static struct clk_init_data clk_uart0_init = {
727 .name = "uart0",
728 .ops = &ios_ops,
729 .parent_names = std_clk_io_parents,
730 .num_parents = ARRAY_SIZE(std_clk_io_parents),
731};
732
733static struct clk_std clk_uart0 = {
734 .enable_bit = 36,
735 .hw = {
736 .init = &clk_uart0_init,
737 },
738};
739
740static struct clk_init_data clk_uart1_init = {
741 .name = "uart1",
742 .ops = &ios_ops,
743 .parent_names = std_clk_io_parents,
744 .num_parents = ARRAY_SIZE(std_clk_io_parents),
745};
746
747static struct clk_std clk_uart1 = {
748 .enable_bit = 37,
749 .hw = {
750 .init = &clk_uart1_init,
751 },
752};
753
754static struct clk_init_data clk_uart2_init = {
755 .name = "uart2",
756 .ops = &ios_ops,
757 .parent_names = std_clk_io_parents,
758 .num_parents = ARRAY_SIZE(std_clk_io_parents),
759};
760
761static struct clk_std clk_uart2 = {
762 .enable_bit = 38,
763 .hw = {
764 .init = &clk_uart2_init,
765 },
766};
767
768static struct clk_init_data clk_usp0_init = {
769 .name = "usp0",
770 .ops = &ios_ops,
771 .parent_names = std_clk_io_parents,
772 .num_parents = ARRAY_SIZE(std_clk_io_parents),
773};
774
775static struct clk_std clk_usp0 = {
776 .enable_bit = 39,
777 .hw = {
778 .init = &clk_usp0_init,
779 },
780};
781
782static struct clk_init_data clk_usp1_init = {
783 .name = "usp1",
784 .ops = &ios_ops,
785 .parent_names = std_clk_io_parents,
786 .num_parents = ARRAY_SIZE(std_clk_io_parents),
787};
788
789static struct clk_std clk_usp1 = {
790 .enable_bit = 40,
791 .hw = {
792 .init = &clk_usp1_init,
793 },
794};
795
796static struct clk_init_data clk_usp2_init = {
797 .name = "usp2",
798 .ops = &ios_ops,
799 .parent_names = std_clk_io_parents,
800 .num_parents = ARRAY_SIZE(std_clk_io_parents),
801};
802
803static struct clk_std clk_usp2 = {
804 .enable_bit = 41,
805 .hw = {
806 .init = &clk_usp2_init,
807 },
808};
809
810static struct clk_init_data clk_vip_init = {
811 .name = "vip",
812 .ops = &ios_ops,
813 .parent_names = std_clk_io_parents,
814 .num_parents = ARRAY_SIZE(std_clk_io_parents),
815};
816
817static struct clk_std clk_vip = {
818 .enable_bit = 42,
819 .hw = {
820 .init = &clk_vip_init,
821 },
822};
823
824static struct clk_init_data clk_spi0_init = {
825 .name = "spi0",
826 .ops = &ios_ops,
827 .parent_names = std_clk_io_parents,
828 .num_parents = ARRAY_SIZE(std_clk_io_parents),
829};
830
831static struct clk_std clk_spi0 = {
832 .enable_bit = 43,
833 .hw = {
834 .init = &clk_spi0_init,
835 },
836};
837
838static struct clk_init_data clk_spi1_init = {
839 .name = "spi1",
840 .ops = &ios_ops,
841 .parent_names = std_clk_io_parents,
842 .num_parents = ARRAY_SIZE(std_clk_io_parents),
843};
844
845static struct clk_std clk_spi1 = {
846 .enable_bit = 44,
847 .hw = {
848 .init = &clk_spi1_init,
849 },
850};
851
852static struct clk_init_data clk_tsc_init = {
853 .name = "tsc",
854 .ops = &ios_ops,
855 .parent_names = std_clk_io_parents,
856 .num_parents = ARRAY_SIZE(std_clk_io_parents),
857};
858
859static struct clk_std clk_tsc = {
860 .enable_bit = 45,
861 .hw = {
862 .init = &clk_tsc_init,
863 },
864};
865
866static struct clk_init_data clk_i2c0_init = {
867 .name = "i2c0",
868 .ops = &ios_ops,
869 .parent_names = std_clk_io_parents,
870 .num_parents = ARRAY_SIZE(std_clk_io_parents),
871};
872
873static struct clk_std clk_i2c0 = {
874 .enable_bit = 46,
875 .hw = {
876 .init = &clk_i2c0_init,
877 },
878};
879
880static struct clk_init_data clk_i2c1_init = {
881 .name = "i2c1",
882 .ops = &ios_ops,
883 .parent_names = std_clk_io_parents,
884 .num_parents = ARRAY_SIZE(std_clk_io_parents),
885};
886
887static struct clk_std clk_i2c1 = {
888 .enable_bit = 47,
889 .hw = {
890 .init = &clk_i2c1_init,
891 },
892};
893
894static struct clk_init_data clk_pwmc_init = {
895 .name = "pwmc",
896 .ops = &ios_ops,
897 .parent_names = std_clk_io_parents,
898 .num_parents = ARRAY_SIZE(std_clk_io_parents),
899};
900
901static struct clk_std clk_pwmc = {
902 .enable_bit = 48,
903 .hw = {
904 .init = &clk_pwmc_init,
905 },
906};
907
908static struct clk_init_data clk_efuse_init = {
909 .name = "efuse",
910 .ops = &ios_ops,
911 .parent_names = std_clk_io_parents,
912 .num_parents = ARRAY_SIZE(std_clk_io_parents),
913};
914
915static struct clk_std clk_efuse = {
916 .enable_bit = 49,
917 .hw = {
918 .init = &clk_efuse_init,
919 },
920};
921
922static struct clk_init_data clk_pulse_init = {
923 .name = "pulse",
924 .ops = &ios_ops,
925 .parent_names = std_clk_io_parents,
926 .num_parents = ARRAY_SIZE(std_clk_io_parents),
927};
928
929static struct clk_std clk_pulse = {
930 .enable_bit = 50,
931 .hw = {
932 .init = &clk_pulse_init,
933 },
934};
935
936static const char *std_clk_dsp_parents[] = {
937 "dsp",
938};
939
940static struct clk_init_data clk_gps_init = {
941 .name = "gps",
942 .ops = &ios_ops,
943 .parent_names = std_clk_dsp_parents,
944 .num_parents = ARRAY_SIZE(std_clk_dsp_parents),
945};
946
947static struct clk_std clk_gps = {
948 .enable_bit = 1,
949 .hw = {
950 .init = &clk_gps_init,
951 },
952};
953
954static struct clk_init_data clk_mf_init = {
955 .name = "mf",
956 .ops = &ios_ops,
957 .parent_names = std_clk_io_parents,
958 .num_parents = ARRAY_SIZE(std_clk_io_parents),
959};
960
961static struct clk_std clk_mf = {
962 .enable_bit = 2,
963 .hw = {
964 .init = &clk_mf_init,
965 },
966};
967
968static const char *std_clk_sys_parents[] = {
969 "sys",
970};
971
972static struct clk_init_data clk_security_init = {
973 .name = "mf",
974 .ops = &ios_ops,
975 .parent_names = std_clk_sys_parents,
976 .num_parents = ARRAY_SIZE(std_clk_sys_parents),
977};
978
979static struct clk_std clk_security = {
980 .enable_bit = 19,
981 .hw = {
982 .init = &clk_security_init,
983 },
984};
985
986static const char *std_clk_usb_parents[] = {
987 "usb_pll",
988};
989
990static struct clk_init_data clk_usb0_init = {
991 .name = "usb0",
992 .ops = &ios_ops,
993 .parent_names = std_clk_usb_parents,
994 .num_parents = ARRAY_SIZE(std_clk_usb_parents),
995};
996
997static struct clk_std clk_usb0 = {
998 .enable_bit = 16,
999 .hw = {
1000 .init = &clk_usb0_init,
1001 },
1002};
1003
1004static struct clk_init_data clk_usb1_init = {
1005 .name = "usb1",
1006 .ops = &ios_ops,
1007 .parent_names = std_clk_usb_parents,
1008 .num_parents = ARRAY_SIZE(std_clk_usb_parents),
1009};
1010
1011static struct clk_std clk_usb1 = {
1012 .enable_bit = 17,
1013 .hw = {
1014 .init = &clk_usb1_init,
1015 },
1016};
1017
1018static struct of_device_id clkc_ids[] = {
1019 { .compatible = "sirf,prima2-clkc" },
1020 {},
1021};
1022
1023static struct of_device_id rsc_ids[] = {
1024 { .compatible = "sirf,prima2-rsc" },
1025 {},
1026};
1027
1028void __init sirfsoc_of_clk_init(void)
1029{
1030 struct clk *clk;
1031 struct device_node *np;
1032
1033 np = of_find_matching_node(NULL, clkc_ids);
1034 if (!np)
1035 panic("unable to find compatible clkc node in dtb\n");
1036
1037 sirfsoc_clk_vbase = of_iomap(np, 0);
1038 if (!sirfsoc_clk_vbase)
1039 panic("unable to map clkc registers\n");
1040
1041 of_node_put(np);
1042
1043 np = of_find_matching_node(NULL, rsc_ids);
1044 if (!np)
1045 panic("unable to find compatible rsc node in dtb\n");
1046
1047 sirfsoc_rsc_vbase = of_iomap(np, 0);
1048 if (!sirfsoc_rsc_vbase)
1049 panic("unable to map rsc registers\n");
1050
1051 of_node_put(np);
1052
1053
1054 /* These are always available (RTC and 26MHz OSC)*/
1055 clk = clk_register_fixed_rate(NULL, "rtc", NULL,
1056 CLK_IS_ROOT, 32768);
1057 BUG_ON(!clk);
1058 clk = clk_register_fixed_rate(NULL, "osc", NULL,
1059 CLK_IS_ROOT, 26000000);
1060 BUG_ON(!clk);
1061
1062 clk = clk_register(NULL, &clk_pll1.hw);
1063 BUG_ON(!clk);
1064 clk = clk_register(NULL, &clk_pll2.hw);
1065 BUG_ON(!clk);
1066 clk = clk_register(NULL, &clk_pll3.hw);
1067 BUG_ON(!clk);
1068 clk = clk_register(NULL, &clk_mem.hw);
1069 BUG_ON(!clk);
1070 clk = clk_register(NULL, &clk_sys.hw);
1071 BUG_ON(!clk);
1072 clk = clk_register(NULL, &clk_security.hw);
1073 BUG_ON(!clk);
1074 clk_register_clkdev(clk, NULL, "b8030000.security");
1075 clk = clk_register(NULL, &clk_dsp.hw);
1076 BUG_ON(!clk);
1077 clk = clk_register(NULL, &clk_gps.hw);
1078 BUG_ON(!clk);
1079 clk_register_clkdev(clk, NULL, "a8010000.gps");
1080 clk = clk_register(NULL, &clk_mf.hw);
1081 BUG_ON(!clk);
1082 clk = clk_register(NULL, &clk_io.hw);
1083 BUG_ON(!clk);
1084 clk_register_clkdev(clk, NULL, "io");
1085 clk = clk_register(NULL, &clk_cpu.hw);
1086 BUG_ON(!clk);
1087 clk_register_clkdev(clk, NULL, "cpu");
1088 clk = clk_register(NULL, &clk_uart0.hw);
1089 BUG_ON(!clk);
1090 clk_register_clkdev(clk, NULL, "b0050000.uart");
1091 clk = clk_register(NULL, &clk_uart1.hw);
1092 BUG_ON(!clk);
1093 clk_register_clkdev(clk, NULL, "b0060000.uart");
1094 clk = clk_register(NULL, &clk_uart2.hw);
1095 BUG_ON(!clk);
1096 clk_register_clkdev(clk, NULL, "b0070000.uart");
1097 clk = clk_register(NULL, &clk_tsc.hw);
1098 BUG_ON(!clk);
1099 clk_register_clkdev(clk, NULL, "b0110000.tsc");
1100 clk = clk_register(NULL, &clk_i2c0.hw);
1101 BUG_ON(!clk);
1102 clk_register_clkdev(clk, NULL, "b00e0000.i2c");
1103 clk = clk_register(NULL, &clk_i2c1.hw);
1104 BUG_ON(!clk);
1105 clk_register_clkdev(clk, NULL, "b00f0000.i2c");
1106 clk = clk_register(NULL, &clk_spi0.hw);
1107 BUG_ON(!clk);
1108 clk_register_clkdev(clk, NULL, "b00d0000.spi");
1109 clk = clk_register(NULL, &clk_spi1.hw);
1110 BUG_ON(!clk);
1111 clk_register_clkdev(clk, NULL, "b0170000.spi");
1112 clk = clk_register(NULL, &clk_pwmc.hw);
1113 BUG_ON(!clk);
1114 clk_register_clkdev(clk, NULL, "b0130000.pwm");
1115 clk = clk_register(NULL, &clk_efuse.hw);
1116 BUG_ON(!clk);
1117 clk_register_clkdev(clk, NULL, "b0140000.efusesys");
1118 clk = clk_register(NULL, &clk_pulse.hw);
1119 BUG_ON(!clk);
1120 clk_register_clkdev(clk, NULL, "b0150000.pulsec");
1121 clk = clk_register(NULL, &clk_dmac0.hw);
1122 BUG_ON(!clk);
1123 clk_register_clkdev(clk, NULL, "b00b0000.dma-controller");
1124 clk = clk_register(NULL, &clk_dmac1.hw);
1125 BUG_ON(!clk);
1126 clk_register_clkdev(clk, NULL, "b0160000.dma-controller");
1127 clk = clk_register(NULL, &clk_nand.hw);
1128 BUG_ON(!clk);
1129 clk_register_clkdev(clk, NULL, "b0030000.nand");
1130 clk = clk_register(NULL, &clk_audio.hw);
1131 BUG_ON(!clk);
1132 clk_register_clkdev(clk, NULL, "b0040000.audio");
1133 clk = clk_register(NULL, &clk_usp0.hw);
1134 BUG_ON(!clk);
1135 clk_register_clkdev(clk, NULL, "b0080000.usp");
1136 clk = clk_register(NULL, &clk_usp1.hw);
1137 BUG_ON(!clk);
1138 clk_register_clkdev(clk, NULL, "b0090000.usp");
1139 clk = clk_register(NULL, &clk_usp2.hw);
1140 BUG_ON(!clk);
1141 clk_register_clkdev(clk, NULL, "b00a0000.usp");
1142 clk = clk_register(NULL, &clk_vip.hw);
1143 BUG_ON(!clk);
1144 clk_register_clkdev(clk, NULL, "b00c0000.vip");
1145 clk = clk_register(NULL, &clk_gfx.hw);
1146 BUG_ON(!clk);
1147 clk_register_clkdev(clk, NULL, "98000000.graphics");
1148 clk = clk_register(NULL, &clk_mm.hw);
1149 BUG_ON(!clk);
1150 clk_register_clkdev(clk, NULL, "a0000000.multimedia");
1151 clk = clk_register(NULL, &clk_lcd.hw);
1152 BUG_ON(!clk);
1153 clk_register_clkdev(clk, NULL, "90010000.display");
1154 clk = clk_register(NULL, &clk_vpp.hw);
1155 BUG_ON(!clk);
1156 clk_register_clkdev(clk, NULL, "90020000.vpp");
1157 clk = clk_register(NULL, &clk_mmc01.hw);
1158 BUG_ON(!clk);
1159 clk = clk_register(NULL, &clk_mmc23.hw);
1160 BUG_ON(!clk);
1161 clk = clk_register(NULL, &clk_mmc45.hw);
1162 BUG_ON(!clk);
1163 clk = clk_register(NULL, &usb_pll_clk_hw);
1164 BUG_ON(!clk);
1165 clk = clk_register(NULL, &clk_usb0.hw);
1166 BUG_ON(!clk);
1167 clk_register_clkdev(clk, NULL, "b00e0000.usb");
1168 clk = clk_register(NULL, &clk_usb1.hw);
1169 BUG_ON(!clk);
1170 clk_register_clkdev(clk, NULL, "b00f0000.usb");
1171}
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index efdfd009c270..56e4495ebeb1 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -558,25 +558,6 @@ int clk_enable(struct clk *clk)
558EXPORT_SYMBOL_GPL(clk_enable); 558EXPORT_SYMBOL_GPL(clk_enable);
559 559
560/** 560/**
561 * clk_get_rate - return the rate of clk
562 * @clk: the clk whose rate is being returned
563 *
564 * Simply returns the cached rate of the clk. Does not query the hardware. If
565 * clk is NULL then returns 0.
566 */
567unsigned long clk_get_rate(struct clk *clk)
568{
569 unsigned long rate;
570
571 mutex_lock(&prepare_lock);
572 rate = __clk_get_rate(clk);
573 mutex_unlock(&prepare_lock);
574
575 return rate;
576}
577EXPORT_SYMBOL_GPL(clk_get_rate);
578
579/**
580 * __clk_round_rate - round the given rate for a clk 561 * __clk_round_rate - round the given rate for a clk
581 * @clk: round the rate of this clock 562 * @clk: round the rate of this clock
582 * 563 *
@@ -702,6 +683,30 @@ static void __clk_recalc_rates(struct clk *clk, unsigned long msg)
702} 683}
703 684
704/** 685/**
686 * clk_get_rate - return the rate of clk
687 * @clk: the clk whose rate is being returned
688 *
689 * Simply returns the cached rate of the clk, unless CLK_GET_RATE_NOCACHE flag
690 * is set, which means a recalc_rate will be issued.
691 * If clk is NULL then returns 0.
692 */
693unsigned long clk_get_rate(struct clk *clk)
694{
695 unsigned long rate;
696
697 mutex_lock(&prepare_lock);
698
699 if (clk && (clk->flags & CLK_GET_RATE_NOCACHE))
700 __clk_recalc_rates(clk, 0);
701
702 rate = __clk_get_rate(clk);
703 mutex_unlock(&prepare_lock);
704
705 return rate;
706}
707EXPORT_SYMBOL_GPL(clk_get_rate);
708
709/**
705 * __clk_speculate_rates 710 * __clk_speculate_rates
706 * @clk: first clk in the subtree 711 * @clk: first clk in the subtree
707 * @parent_rate: the "future" rate of clk's parent 712 * @parent_rate: the "future" rate of clk's parent
@@ -1582,6 +1587,20 @@ struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec,
1582} 1587}
1583EXPORT_SYMBOL_GPL(of_clk_src_simple_get); 1588EXPORT_SYMBOL_GPL(of_clk_src_simple_get);
1584 1589
1590struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data)
1591{
1592 struct clk_onecell_data *clk_data = data;
1593 unsigned int idx = clkspec->args[0];
1594
1595 if (idx >= clk_data->clk_num) {
1596 pr_err("%s: invalid clock index %d\n", __func__, idx);
1597 return ERR_PTR(-EINVAL);
1598 }
1599
1600 return clk_data->clks[idx];
1601}
1602EXPORT_SYMBOL_GPL(of_clk_src_onecell_get);
1603
1585/** 1604/**
1586 * of_clk_add_provider() - Register a clock provider for a node 1605 * of_clk_add_provider() - Register a clock provider for a node
1587 * @np: Device node pointer associated with clock provider 1606 * @np: Device node pointer associated with clock provider
diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
new file mode 100644
index 000000000000..392d78044ce3
--- /dev/null
+++ b/drivers/clk/mmp/Makefile
@@ -0,0 +1,9 @@
1#
2# Makefile for mmp specific clk
3#
4
5obj-y += clk-apbc.o clk-apmu.o clk-frac.o
6
7obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
8obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
9obj-$(CONFIG_CPU_MMP2) += clk-mmp2.o
diff --git a/drivers/clk/mmp/clk-apbc.c b/drivers/clk/mmp/clk-apbc.c
new file mode 100644
index 000000000000..d14120eaa71f
--- /dev/null
+++ b/drivers/clk/mmp/clk-apbc.c
@@ -0,0 +1,152 @@
1/*
2 * mmp APB clock operation source file
3 *
4 * Copyright (C) 2012 Marvell
5 * Chao Xie <xiechao.mail@gmail.com>
6 *
7 * This file is licensed under the terms of the GNU General Public
8 * License version 2. This program is licensed "as is" without any
9 * warranty of any kind, whether express or implied.
10 */
11
12#include <linux/kernel.h>
13#include <linux/clk.h>
14#include <linux/io.h>
15#include <linux/err.h>
16#include <linux/delay.h>
17#include <linux/slab.h>
18
19#include "clk.h"
20
21/* Common APB clock register bit definitions */
22#define APBC_APBCLK (1 << 0) /* APB Bus Clock Enable */
23#define APBC_FNCLK (1 << 1) /* Functional Clock Enable */
24#define APBC_RST (1 << 2) /* Reset Generation */
25#define APBC_POWER (1 << 7) /* Reset Generation */
26
27#define to_clk_apbc(hw) container_of(hw, struct clk_apbc, hw)
28struct clk_apbc {
29 struct clk_hw hw;
30 void __iomem *base;
31 unsigned int delay;
32 unsigned int flags;
33 spinlock_t *lock;
34};
35
36static int clk_apbc_prepare(struct clk_hw *hw)
37{
38 struct clk_apbc *apbc = to_clk_apbc(hw);
39 unsigned int data;
40 unsigned long flags = 0;
41
42 /*
43 * It may share same register as MUX clock,
44 * and it will impact FNCLK enable. Spinlock is needed
45 */
46 if (apbc->lock)
47 spin_lock_irqsave(apbc->lock, flags);
48
49 data = readl_relaxed(apbc->base);
50 if (apbc->flags & APBC_POWER_CTRL)
51 data |= APBC_POWER;
52 data |= APBC_FNCLK;
53 writel_relaxed(data, apbc->base);
54
55 if (apbc->lock)
56 spin_unlock_irqrestore(apbc->lock, flags);
57
58 udelay(apbc->delay);
59
60 if (apbc->lock)
61 spin_lock_irqsave(apbc->lock, flags);
62
63 data = readl_relaxed(apbc->base);
64 data |= APBC_APBCLK;
65 writel_relaxed(data, apbc->base);
66
67 if (apbc->lock)
68 spin_unlock_irqrestore(apbc->lock, flags);
69
70 udelay(apbc->delay);
71
72 if (!(apbc->flags & APBC_NO_BUS_CTRL)) {
73 if (apbc->lock)
74 spin_lock_irqsave(apbc->lock, flags);
75
76 data = readl_relaxed(apbc->base);
77 data &= ~APBC_RST;
78 writel_relaxed(data, apbc->base);
79
80 if (apbc->lock)
81 spin_unlock_irqrestore(apbc->lock, flags);
82 }
83
84 return 0;
85}
86
87static void clk_apbc_unprepare(struct clk_hw *hw)
88{
89 struct clk_apbc *apbc = to_clk_apbc(hw);
90 unsigned long data;
91 unsigned long flags = 0;
92
93 if (apbc->lock)
94 spin_lock_irqsave(apbc->lock, flags);
95
96 data = readl_relaxed(apbc->base);
97 if (apbc->flags & APBC_POWER_CTRL)
98 data &= ~APBC_POWER;
99 data &= ~APBC_FNCLK;
100 writel_relaxed(data, apbc->base);
101
102 if (apbc->lock)
103 spin_unlock_irqrestore(apbc->lock, flags);
104
105 udelay(10);
106
107 if (apbc->lock)
108 spin_lock_irqsave(apbc->lock, flags);
109
110 data = readl_relaxed(apbc->base);
111 data &= ~APBC_APBCLK;
112 writel_relaxed(data, apbc->base);
113
114 if (apbc->lock)
115 spin_unlock_irqrestore(apbc->lock, flags);
116}
117
118struct clk_ops clk_apbc_ops = {
119 .prepare = clk_apbc_prepare,
120 .unprepare = clk_apbc_unprepare,
121};
122
123struct clk *mmp_clk_register_apbc(const char *name, const char *parent_name,
124 void __iomem *base, unsigned int delay,
125 unsigned int apbc_flags, spinlock_t *lock)
126{
127 struct clk_apbc *apbc;
128 struct clk *clk;
129 struct clk_init_data init;
130
131 apbc = kzalloc(sizeof(*apbc), GFP_KERNEL);
132 if (!apbc)
133 return NULL;
134
135 init.name = name;
136 init.ops = &clk_apbc_ops;
137 init.flags = CLK_SET_RATE_PARENT;
138 init.parent_names = (parent_name ? &parent_name : NULL);
139 init.num_parents = (parent_name ? 1 : 0);
140
141 apbc->base = base;
142 apbc->delay = delay;
143 apbc->flags = apbc_flags;
144 apbc->lock = lock;
145 apbc->hw.init = &init;
146
147 clk = clk_register(NULL, &apbc->hw);
148 if (IS_ERR(clk))
149 kfree(apbc);
150
151 return clk;
152}
diff --git a/drivers/clk/mmp/clk-apmu.c b/drivers/clk/mmp/clk-apmu.c
new file mode 100644
index 000000000000..abe182b2377f
--- /dev/null
+++ b/drivers/clk/mmp/clk-apmu.c
@@ -0,0 +1,97 @@
1/*
2 * mmp AXI peripharal clock operation source file
3 *
4 * Copyright (C) 2012 Marvell
5 * Chao Xie <xiechao.mail@gmail.com>
6 *
7 * This file is licensed under the terms of the GNU General Public
8 * License version 2. This program is licensed "as is" without any
9 * warranty of any kind, whether express or implied.
10 */
11
12#include <linux/kernel.h>
13#include <linux/clk.h>
14#include <linux/io.h>
15#include <linux/err.h>
16#include <linux/delay.h>
17#include <linux/slab.h>
18
19#include "clk.h"
20
21#define to_clk_apmu(clk) (container_of(clk, struct clk_apmu, clk))
22struct clk_apmu {
23 struct clk_hw hw;
24 void __iomem *base;
25 u32 rst_mask;
26 u32 enable_mask;
27 spinlock_t *lock;
28};
29
30static int clk_apmu_enable(struct clk_hw *hw)
31{
32 struct clk_apmu *apmu = to_clk_apmu(hw);
33 unsigned long data;
34 unsigned long flags = 0;
35
36 if (apmu->lock)
37 spin_lock_irqsave(apmu->lock, flags);
38
39 data = readl_relaxed(apmu->base) | apmu->enable_mask;
40 writel_relaxed(data, apmu->base);
41
42 if (apmu->lock)
43 spin_unlock_irqrestore(apmu->lock, flags);
44
45 return 0;
46}
47
48static void clk_apmu_disable(struct clk_hw *hw)
49{
50 struct clk_apmu *apmu = to_clk_apmu(hw);
51 unsigned long data;
52 unsigned long flags = 0;
53
54 if (apmu->lock)
55 spin_lock_irqsave(apmu->lock, flags);
56
57 data = readl_relaxed(apmu->base) & ~apmu->enable_mask;
58 writel_relaxed(data, apmu->base);
59
60 if (apmu->lock)
61 spin_unlock_irqrestore(apmu->lock, flags);
62}
63
64struct clk_ops clk_apmu_ops = {
65 .enable = clk_apmu_enable,
66 .disable = clk_apmu_disable,
67};
68
69struct clk *mmp_clk_register_apmu(const char *name, const char *parent_name,
70 void __iomem *base, u32 enable_mask, spinlock_t *lock)
71{
72 struct clk_apmu *apmu;
73 struct clk *clk;
74 struct clk_init_data init;
75
76 apmu = kzalloc(sizeof(*apmu), GFP_KERNEL);
77 if (!apmu)
78 return NULL;
79
80 init.name = name;
81 init.ops = &clk_apmu_ops;
82 init.flags = CLK_SET_RATE_PARENT;
83 init.parent_names = (parent_name ? &parent_name : NULL);
84 init.num_parents = (parent_name ? 1 : 0);
85
86 apmu->base = base;
87 apmu->enable_mask = enable_mask;
88 apmu->lock = lock;
89 apmu->hw.init = &init;
90
91 clk = clk_register(NULL, &apmu->hw);
92
93 if (IS_ERR(clk))
94 kfree(apmu);
95
96 return clk;
97}
diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c
new file mode 100644
index 000000000000..80c1dd15d15c
--- /dev/null
+++ b/drivers/clk/mmp/clk-frac.c
@@ -0,0 +1,153 @@
1/*
2 * mmp factor clock operation source file
3 *
4 * Copyright (C) 2012 Marvell
5 * Chao Xie <xiechao.mail@gmail.com>
6 *
7 * This file is licensed under the terms of the GNU General Public
8 * License version 2. This program is licensed "as is" without any
9 * warranty of any kind, whether express or implied.
10 */
11
12#include <linux/clk-provider.h>
13#include <linux/slab.h>
14#include <linux/io.h>
15#include <linux/err.h>
16
17#include "clk.h"
18/*
19 * It is M/N clock
20 *
21 * Fout from synthesizer can be given from two equations:
22 * numerator/denominator = Fin / (Fout * factor)
23 */
24
25#define to_clk_factor(hw) container_of(hw, struct clk_factor, hw)
26struct clk_factor {
27 struct clk_hw hw;
28 void __iomem *base;
29 struct clk_factor_masks *masks;
30 struct clk_factor_tbl *ftbl;
31 unsigned int ftbl_cnt;
32};
33
34static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate,
35 unsigned long *prate)
36{
37 struct clk_factor *factor = to_clk_factor(hw);
38 unsigned long rate = 0, prev_rate;
39 int i;
40
41 for (i = 0; i < factor->ftbl_cnt; i++) {
42 prev_rate = rate;
43 rate = (((*prate / 10000) * factor->ftbl[i].num) /
44 (factor->ftbl[i].den * factor->masks->factor)) * 10000;
45 if (rate > drate)
46 break;
47 }
48 if (i == 0)
49 return rate;
50 else
51 return prev_rate;
52}
53
54static unsigned long clk_factor_recalc_rate(struct clk_hw *hw,
55 unsigned long parent_rate)
56{
57 struct clk_factor *factor = to_clk_factor(hw);
58 struct clk_factor_masks *masks = factor->masks;
59 unsigned int val, num, den;
60
61 val = readl_relaxed(factor->base);
62
63 /* calculate numerator */
64 num = (val >> masks->num_shift) & masks->num_mask;
65
66 /* calculate denominator */
67 den = (val >> masks->den_shift) & masks->num_mask;
68
69 if (!den)
70 return 0;
71
72 return (((parent_rate / 10000) * den) /
73 (num * factor->masks->factor)) * 10000;
74}
75
76/* Configures new clock rate*/
77static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate,
78 unsigned long prate)
79{
80 struct clk_factor *factor = to_clk_factor(hw);
81 struct clk_factor_masks *masks = factor->masks;
82 int i;
83 unsigned long val;
84 unsigned long prev_rate, rate = 0;
85
86 for (i = 0; i < factor->ftbl_cnt; i++) {
87 prev_rate = rate;
88 rate = (((prate / 10000) * factor->ftbl[i].num) /
89 (factor->ftbl[i].den * factor->masks->factor)) * 10000;
90 if (rate > drate)
91 break;
92 }
93 if (i > 0)
94 i--;
95
96 val = readl_relaxed(factor->base);
97
98 val &= ~(masks->num_mask << masks->num_shift);
99 val |= (factor->ftbl[i].num & masks->num_mask) << masks->num_shift;
100
101 val &= ~(masks->den_mask << masks->den_shift);
102 val |= (factor->ftbl[i].den & masks->den_mask) << masks->den_shift;
103
104 writel_relaxed(val, factor->base);
105
106 return 0;
107}
108
109static struct clk_ops clk_factor_ops = {
110 .recalc_rate = clk_factor_recalc_rate,
111 .round_rate = clk_factor_round_rate,
112 .set_rate = clk_factor_set_rate,
113};
114
115struct clk *mmp_clk_register_factor(const char *name, const char *parent_name,
116 unsigned long flags, void __iomem *base,
117 struct clk_factor_masks *masks, struct clk_factor_tbl *ftbl,
118 unsigned int ftbl_cnt)
119{
120 struct clk_factor *factor;
121 struct clk_init_data init;
122 struct clk *clk;
123
124 if (!masks) {
125 pr_err("%s: must pass a clk_factor_mask\n", __func__);
126 return ERR_PTR(-EINVAL);
127 }
128
129 factor = kzalloc(sizeof(*factor), GFP_KERNEL);
130 if (!factor) {
131 pr_err("%s: could not allocate factor clk\n", __func__);
132 return ERR_PTR(-ENOMEM);
133 }
134
135 /* struct clk_aux assignments */
136 factor->base = base;
137 factor->masks = masks;
138 factor->ftbl = ftbl;
139 factor->ftbl_cnt = ftbl_cnt;
140 factor->hw.init = &init;
141
142 init.name = name;
143 init.ops = &clk_factor_ops;
144 init.flags = flags;
145 init.parent_names = &parent_name;
146 init.num_parents = 1;
147
148 clk = clk_register(NULL, &factor->hw);
149 if (IS_ERR_OR_NULL(clk))
150 kfree(factor);
151
152 return clk;
153}
diff --git a/drivers/clk/mmp/clk-mmp2.c b/drivers/clk/mmp/clk-mmp2.c
new file mode 100644
index 000000000000..ade435820c7e
--- /dev/null
+++ b/drivers/clk/mmp/clk-mmp2.c
@@ -0,0 +1,449 @@
1/*
2 * mmp2 clock framework source file
3 *
4 * Copyright (C) 2012 Marvell
5 * Chao Xie <xiechao.mail@gmail.com>
6 *
7 * This file is licensed under the terms of the GNU General Public
8 * License version 2. This program is licensed "as is" without any
9 * warranty of any kind, whether express or implied.
10 */
11
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/spinlock.h>
15#include <linux/io.h>
16#include <linux/delay.h>
17#include <linux/err.h>
18
19#include <mach/addr-map.h>
20
21#include "clk.h"
22
23#define APBC_RTC 0x0
24#define APBC_TWSI0 0x4
25#define APBC_TWSI1 0x8
26#define APBC_TWSI2 0xc
27#define APBC_TWSI3 0x10
28#define APBC_TWSI4 0x7c
29#define APBC_TWSI5 0x80
30#define APBC_KPC 0x18
31#define APBC_UART0 0x2c
32#define APBC_UART1 0x30
33#define APBC_UART2 0x34
34#define APBC_UART3 0x88
35#define APBC_GPIO 0x38
36#define APBC_PWM0 0x3c
37#define APBC_PWM1 0x40
38#define APBC_PWM2 0x44
39#define APBC_PWM3 0x48
40#define APBC_SSP0 0x50
41#define APBC_SSP1 0x54
42#define APBC_SSP2 0x58
43#define APBC_SSP3 0x5c
44#define APMU_SDH0 0x54
45#define APMU_SDH1 0x58
46#define APMU_SDH2 0xe8
47#define APMU_SDH3 0xec
48#define APMU_USB 0x5c
49#define APMU_DISP0 0x4c
50#define APMU_DISP1 0x110
51#define APMU_CCIC0 0x50
52#define APMU_CCIC1 0xf4
53#define MPMU_UART_PLL 0x14
54
55static DEFINE_SPINLOCK(clk_lock);
56
57static struct clk_factor_masks uart_factor_masks = {
58 .factor = 2,
59 .num_mask = 0x1fff,
60 .den_mask = 0x1fff,
61 .num_shift = 16,
62 .den_shift = 0,
63};
64
65static struct clk_factor_tbl uart_factor_tbl[] = {
66 {.num = 14634, .den = 2165}, /*14.745MHZ */
67 {.num = 3521, .den = 689}, /*19.23MHZ */
68 {.num = 9679, .den = 5728}, /*58.9824MHZ */
69 {.num = 15850, .den = 9451}, /*59.429MHZ */
70};
71
72static const char *uart_parent[] = {"uart_pll", "vctcxo"};
73static const char *ssp_parent[] = {"vctcxo_4", "vctcxo_2", "vctcxo", "pll1_16"};
74static const char *sdh_parent[] = {"pll1_4", "pll2", "usb_pll", "pll1"};
75static const char *disp_parent[] = {"pll1", "pll1_16", "pll2", "vctcxo"};
76static const char *ccic_parent[] = {"pll1_2", "pll1_16", "vctcxo"};
77
78void __init mmp2_clk_init(void)
79{
80 struct clk *clk;
81 struct clk *vctcxo;
82 void __iomem *mpmu_base;
83 void __iomem *apmu_base;
84 void __iomem *apbc_base;
85
86 mpmu_base = ioremap(APB_PHYS_BASE + 0x50000, SZ_4K);
87 if (mpmu_base == NULL) {
88 pr_err("error to ioremap MPMU base\n");
89 return;
90 }
91
92 apmu_base = ioremap(AXI_PHYS_BASE + 0x82800, SZ_4K);
93 if (apmu_base == NULL) {
94 pr_err("error to ioremap APMU base\n");
95 return;
96 }
97
98 apbc_base = ioremap(APB_PHYS_BASE + 0x15000, SZ_4K);
99 if (apbc_base == NULL) {
100 pr_err("error to ioremap APBC base\n");
101 return;
102 }
103
104 clk = clk_register_fixed_rate(NULL, "clk32", NULL, CLK_IS_ROOT, 3200);
105 clk_register_clkdev(clk, "clk32", NULL);
106
107 vctcxo = clk_register_fixed_rate(NULL, "vctcxo", NULL, CLK_IS_ROOT,
108 26000000);
109 clk_register_clkdev(vctcxo, "vctcxo", NULL);
110
111 clk = clk_register_fixed_rate(NULL, "pll1", NULL, CLK_IS_ROOT,
112 800000000);
113 clk_register_clkdev(clk, "pll1", NULL);
114
115 clk = clk_register_fixed_rate(NULL, "usb_pll", NULL, CLK_IS_ROOT,
116 480000000);
117 clk_register_clkdev(clk, "usb_pll", NULL);
118
119 clk = clk_register_fixed_rate(NULL, "pll2", NULL, CLK_IS_ROOT,
120 960000000);
121 clk_register_clkdev(clk, "pll2", NULL);
122
123 clk = clk_register_fixed_factor(NULL, "pll1_2", "pll1",
124 CLK_SET_RATE_PARENT, 1, 2);
125 clk_register_clkdev(clk, "pll1_2", NULL);
126
127 clk = clk_register_fixed_factor(NULL, "pll1_4", "pll1_2",
128 CLK_SET_RATE_PARENT, 1, 2);
129 clk_register_clkdev(clk, "pll1_4", NULL);
130
131 clk = clk_register_fixed_factor(NULL, "pll1_8", "pll1_4",
132 CLK_SET_RATE_PARENT, 1, 2);
133 clk_register_clkdev(clk, "pll1_8", NULL);
134
135 clk = clk_register_fixed_factor(NULL, "pll1_16", "pll1_8",
136 CLK_SET_RATE_PARENT, 1, 2);
137 clk_register_clkdev(clk, "pll1_16", NULL);
138
139 clk = clk_register_fixed_factor(NULL, "pll1_20", "pll1_4",
140 CLK_SET_RATE_PARENT, 1, 5);
141 clk_register_clkdev(clk, "pll1_20", NULL);
142
143 clk = clk_register_fixed_factor(NULL, "pll1_3", "pll1",
144 CLK_SET_RATE_PARENT, 1, 3);
145 clk_register_clkdev(clk, "pll1_3", NULL);
146
147 clk = clk_register_fixed_factor(NULL, "pll1_6", "pll1_3",
148 CLK_SET_RATE_PARENT, 1, 2);
149 clk_register_clkdev(clk, "pll1_6", NULL);
150
151 clk = clk_register_fixed_factor(NULL, "pll1_12", "pll1_6",
152 CLK_SET_RATE_PARENT, 1, 2);
153 clk_register_clkdev(clk, "pll1_12", NULL);
154
155 clk = clk_register_fixed_factor(NULL, "pll2_2", "pll2",
156 CLK_SET_RATE_PARENT, 1, 2);
157 clk_register_clkdev(clk, "pll2_2", NULL);
158
159 clk = clk_register_fixed_factor(NULL, "pll2_4", "pll2_2",
160 CLK_SET_RATE_PARENT, 1, 2);
161 clk_register_clkdev(clk, "pll2_4", NULL);
162
163 clk = clk_register_fixed_factor(NULL, "pll2_8", "pll2_4",
164 CLK_SET_RATE_PARENT, 1, 2);
165 clk_register_clkdev(clk, "pll2_8", NULL);
166
167 clk = clk_register_fixed_factor(NULL, "pll2_16", "pll2_8",
168 CLK_SET_RATE_PARENT, 1, 2);
169 clk_register_clkdev(clk, "pll2_16", NULL);
170
171 clk = clk_register_fixed_factor(NULL, "pll2_3", "pll2",
172 CLK_SET_RATE_PARENT, 1, 3);
173 clk_register_clkdev(clk, "pll2_3", NULL);
174
175 clk = clk_register_fixed_factor(NULL, "pll2_6", "pll2_3",
176 CLK_SET_RATE_PARENT, 1, 2);
177 clk_register_clkdev(clk, "pll2_6", NULL);
178
179 clk = clk_register_fixed_factor(NULL, "pll2_12", "pll2_6",
180 CLK_SET_RATE_PARENT, 1, 2);
181 clk_register_clkdev(clk, "pll2_12", NULL);
182
183 clk = clk_register_fixed_factor(NULL, "vctcxo_2", "vctcxo",
184 CLK_SET_RATE_PARENT, 1, 2);
185 clk_register_clkdev(clk, "vctcxo_2", NULL);
186
187 clk = clk_register_fixed_factor(NULL, "vctcxo_4", "vctcxo_2",
188 CLK_SET_RATE_PARENT, 1, 2);
189 clk_register_clkdev(clk, "vctcxo_4", NULL);
190
191 clk = mmp_clk_register_factor("uart_pll", "pll1_4", 0,
192 mpmu_base + MPMU_UART_PLL,
193 &uart_factor_masks, uart_factor_tbl,
194 ARRAY_SIZE(uart_factor_tbl));
195 clk_set_rate(clk, 14745600);
196 clk_register_clkdev(clk, "uart_pll", NULL);
197
198 clk = mmp_clk_register_apbc("twsi0", "vctcxo",
199 apbc_base + APBC_TWSI0, 10, 0, &clk_lock);
200 clk_register_clkdev(clk, NULL, "pxa2xx-i2c.0");
201
202 clk = mmp_clk_register_apbc("twsi1", "vctcxo",
203 apbc_base + APBC_TWSI1, 10, 0, &clk_lock);
204 clk_register_clkdev(clk, NULL, "pxa2xx-i2c.1");
205
206 clk = mmp_clk_register_apbc("twsi2", "vctcxo",
207 apbc_base + APBC_TWSI2, 10, 0, &clk_lock);
208 clk_register_clkdev(clk, NULL, "pxa2xx-i2c.2");
209
210 clk = mmp_clk_register_apbc("twsi3", "vctcxo",
211 apbc_base + APBC_TWSI3, 10, 0, &clk_lock);
212 clk_register_clkdev(clk, NULL, "pxa2xx-i2c.3");
213
214 clk = mmp_clk_register_apbc("twsi4", "vctcxo",
215 apbc_base + APBC_TWSI4, 10, 0, &clk_lock);
216 clk_register_clkdev(clk, NULL, "pxa2xx-i2c.4");
217
218 clk = mmp_clk_register_apbc("twsi5", "vctcxo",
219 apbc_base + APBC_TWSI5, 10, 0, &clk_lock);
220 clk_register_clkdev(clk, NULL, "pxa2xx-i2c.5");
221
222 clk = mmp_clk_register_apbc("gpio", "vctcxo",
223 apbc_base + APBC_GPIO, 10, 0, &clk_lock);
224 clk_register_clkdev(clk, NULL, "pxa-gpio");
225
226 clk = mmp_clk_register_apbc("kpc", "clk32",
227 apbc_base + APBC_KPC, 10, 0, &clk_lock);
228 clk_register_clkdev(clk, NULL, "pxa27x-keypad");
229
230 clk = mmp_clk_register_apbc("rtc", "clk32",
231 apbc_base + APBC_RTC, 10, 0, &clk_lock);
232 clk_register_clkdev(clk, NULL, "mmp-rtc");
233
234 clk = mmp_clk_register_apbc("pwm0", "vctcxo",
235 apbc_base + APBC_PWM0, 10, 0, &clk_lock);
236 clk_register_clkdev(clk, NULL, "mmp2-pwm.0");
237
238 clk = mmp_clk_register_apbc("pwm1", "vctcxo",
239 apbc_base + APBC_PWM1, 10, 0, &clk_lock);
240 clk_register_clkdev(clk, NULL, "mmp2-pwm.1");
241
242 clk = mmp_clk_register_apbc("pwm2", "vctcxo",
243 apbc_base + APBC_PWM2, 10, 0, &clk_lock);
244 clk_register_clkdev(clk, NULL, "mmp2-pwm.2");
245
246 clk = mmp_clk_register_apbc("pwm3", "vctcxo",
247 apbc_base + APBC_PWM3, 10, 0, &clk_lock);
248 clk_register_clkdev(clk, NULL, "mmp2-pwm.3");
249
250 clk = clk_register_mux(NULL, "uart0_mux", uart_parent,
251 ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
252 apbc_base + APBC_UART0, 4, 3, 0, &clk_lock);
253 clk_set_parent(clk, vctcxo);
254 clk_register_clkdev(clk, "uart_mux.0", NULL);
255
256 clk = mmp_clk_register_apbc("uart0", "uart0_mux",
257 apbc_base + APBC_UART0, 10, 0, &clk_lock);
258 clk_register_clkdev(clk, NULL, "pxa2xx-uart.0");
259
260 clk = clk_register_mux(NULL, "uart1_mux", uart_parent,
261 ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
262 apbc_base + APBC_UART1, 4, 3, 0, &clk_lock);
263 clk_set_parent(clk, vctcxo);
264 clk_register_clkdev(clk, "uart_mux.1", NULL);
265
266 clk = mmp_clk_register_apbc("uart1", "uart1_mux",
267 apbc_base + APBC_UART1, 10, 0, &clk_lock);
268 clk_register_clkdev(clk, NULL, "pxa2xx-uart.1");
269
270 clk = clk_register_mux(NULL, "uart2_mux", uart_parent,
271 ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
272 apbc_base + APBC_UART2, 4, 3, 0, &clk_lock);
273 clk_set_parent(clk, vctcxo);
274 clk_register_clkdev(clk, "uart_mux.2", NULL);
275
276 clk = mmp_clk_register_apbc("uart2", "uart2_mux",
277 apbc_base + APBC_UART2, 10, 0, &clk_lock);
278 clk_register_clkdev(clk, NULL, "pxa2xx-uart.2");
279
280 clk = clk_register_mux(NULL, "uart3_mux", uart_parent,
281 ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
282 apbc_base + APBC_UART3, 4, 3, 0, &clk_lock);
283 clk_set_parent(clk, vctcxo);
284 clk_register_clkdev(clk, "uart_mux.3", NULL);
285
286 clk = mmp_clk_register_apbc("uart3", "uart3_mux",
287 apbc_base + APBC_UART3, 10, 0, &clk_lock);
288 clk_register_clkdev(clk, NULL, "pxa2xx-uart.3");
289
290 clk = clk_register_mux(NULL, "ssp0_mux", ssp_parent,
291 ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT,
292 apbc_base + APBC_SSP0, 4, 3, 0, &clk_lock);
293 clk_register_clkdev(clk, "uart_mux.0", NULL);
294
295 clk = mmp_clk_register_apbc("ssp0", "ssp0_mux",
296 apbc_base + APBC_SSP0, 10, 0, &clk_lock);
297 clk_register_clkdev(clk, NULL, "mmp-ssp.0");
298
299 clk = clk_register_mux(NULL, "ssp1_mux", ssp_parent,
300 ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT,
301 apbc_base + APBC_SSP1, 4, 3, 0, &clk_lock);
302 clk_register_clkdev(clk, "ssp_mux.1", NULL);
303
304 clk = mmp_clk_register_apbc("ssp1", "ssp1_mux",
305 apbc_base + APBC_SSP1, 10, 0, &clk_lock);
306 clk_register_clkdev(clk, NULL, "mmp-ssp.1");
307
308 clk = clk_register_mux(NULL, "ssp2_mux", ssp_parent,
309 ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT,
310 apbc_base + APBC_SSP2, 4, 3, 0, &clk_lock);
311 clk_register_clkdev(clk, "ssp_mux.2", NULL);
312
313 clk = mmp_clk_register_apbc("ssp2", "ssp2_mux",
314 apbc_base + APBC_SSP2, 10, 0, &clk_lock);
315 clk_register_clkdev(clk, NULL, "mmp-ssp.2");
316
317 clk = clk_register_mux(NULL, "ssp3_mux", ssp_parent,
318 ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT,
319 apbc_base + APBC_SSP3, 4, 3, 0, &clk_lock);
320 clk_register_clkdev(clk, "ssp_mux.3", NULL);
321
322 clk = mmp_clk_register_apbc("ssp3", "ssp3_mux",
323 apbc_base + APBC_SSP3, 10, 0, &clk_lock);
324 clk_register_clkdev(clk, NULL, "mmp-ssp.3");
325
326 clk = clk_register_mux(NULL, "sdh_mux", sdh_parent,
327 ARRAY_SIZE(sdh_parent), CLK_SET_RATE_PARENT,
328 apmu_base + APMU_SDH0, 8, 2, 0, &clk_lock);
329 clk_register_clkdev(clk, "sdh_mux", NULL);
330
331 clk = clk_register_divider(NULL, "sdh_div", "sdh_mux",
332 CLK_SET_RATE_PARENT, apmu_base + APMU_SDH0,
333 10, 4, CLK_DIVIDER_ONE_BASED, &clk_lock);
334 clk_register_clkdev(clk, "sdh_div", NULL);
335
336 clk = mmp_clk_register_apmu("sdh0", "sdh_div", apmu_base + APMU_SDH0,
337 0x1b, &clk_lock);
338 clk_register_clkdev(clk, NULL, "sdhci-pxav3.0");
339
340 clk = mmp_clk_register_apmu("sdh1", "sdh_div", apmu_base + APMU_SDH1,
341 0x1b, &clk_lock);
342 clk_register_clkdev(clk, NULL, "sdhci-pxav3.1");
343
344 clk = mmp_clk_register_apmu("sdh2", "sdh_div", apmu_base + APMU_SDH2,
345 0x1b, &clk_lock);
346 clk_register_clkdev(clk, NULL, "sdhci-pxav3.2");
347
348 clk = mmp_clk_register_apmu("sdh3", "sdh_div", apmu_base + APMU_SDH3,
349 0x1b, &clk_lock);
350 clk_register_clkdev(clk, NULL, "sdhci-pxav3.3");
351
352 clk = mmp_clk_register_apmu("usb", "usb_pll", apmu_base + APMU_USB,
353 0x9, &clk_lock);
354 clk_register_clkdev(clk, "usb_clk", NULL);
355
356 clk = clk_register_mux(NULL, "disp0_mux", disp_parent,
357 ARRAY_SIZE(disp_parent), CLK_SET_RATE_PARENT,
358 apmu_base + APMU_DISP0, 6, 2, 0, &clk_lock);
359 clk_register_clkdev(clk, "disp_mux.0", NULL);
360
361 clk = clk_register_divider(NULL, "disp0_div", "disp0_mux",
362 CLK_SET_RATE_PARENT, apmu_base + APMU_DISP0,
363 8, 4, CLK_DIVIDER_ONE_BASED, &clk_lock);
364 clk_register_clkdev(clk, "disp_div.0", NULL);
365
366 clk = mmp_clk_register_apmu("disp0", "disp0_div",
367 apmu_base + APMU_DISP0, 0x1b, &clk_lock);
368 clk_register_clkdev(clk, NULL, "mmp-disp.0");
369
370 clk = clk_register_divider(NULL, "disp0_sphy_div", "disp0_mux", 0,
371 apmu_base + APMU_DISP0, 15, 5, 0, &clk_lock);
372 clk_register_clkdev(clk, "disp_sphy_div.0", NULL);
373
374 clk = mmp_clk_register_apmu("disp0_sphy", "disp0_sphy_div",
375 apmu_base + APMU_DISP0, 0x1024, &clk_lock);
376 clk_register_clkdev(clk, "disp_sphy.0", NULL);
377
378 clk = clk_register_mux(NULL, "disp1_mux", disp_parent,
379 ARRAY_SIZE(disp_parent), CLK_SET_RATE_PARENT,
380 apmu_base + APMU_DISP1, 6, 2, 0, &clk_lock);
381 clk_register_clkdev(clk, "disp_mux.1", NULL);
382
383 clk = clk_register_divider(NULL, "disp1_div", "disp1_mux",
384 CLK_SET_RATE_PARENT, apmu_base + APMU_DISP1,
385 8, 4, CLK_DIVIDER_ONE_BASED, &clk_lock);
386 clk_register_clkdev(clk, "disp_div.1", NULL);
387
388 clk = mmp_clk_register_apmu("disp1", "disp1_div",
389 apmu_base + APMU_DISP1, 0x1b, &clk_lock);
390 clk_register_clkdev(clk, NULL, "mmp-disp.1");
391
392 clk = mmp_clk_register_apmu("ccic_arbiter", "vctcxo",
393 apmu_base + APMU_CCIC0, 0x1800, &clk_lock);
394 clk_register_clkdev(clk, "ccic_arbiter", NULL);
395
396 clk = clk_register_mux(NULL, "ccic0_mux", ccic_parent,
397 ARRAY_SIZE(ccic_parent), CLK_SET_RATE_PARENT,
398 apmu_base + APMU_CCIC0, 6, 2, 0, &clk_lock);
399 clk_register_clkdev(clk, "ccic_mux.0", NULL);
400
401 clk = clk_register_divider(NULL, "ccic0_div", "ccic0_mux",
402 CLK_SET_RATE_PARENT, apmu_base + APMU_CCIC0,
403 17, 4, CLK_DIVIDER_ONE_BASED, &clk_lock);
404 clk_register_clkdev(clk, "ccic_div.0", NULL);
405
406 clk = mmp_clk_register_apmu("ccic0", "ccic0_div",
407 apmu_base + APMU_CCIC0, 0x1b, &clk_lock);
408 clk_register_clkdev(clk, "fnclk", "mmp-ccic.0");
409
410 clk = mmp_clk_register_apmu("ccic0_phy", "ccic0_div",
411 apmu_base + APMU_CCIC0, 0x24, &clk_lock);
412 clk_register_clkdev(clk, "phyclk", "mmp-ccic.0");
413
414 clk = clk_register_divider(NULL, "ccic0_sphy_div", "ccic0_div",
415 CLK_SET_RATE_PARENT, apmu_base + APMU_CCIC0,
416 10, 5, 0, &clk_lock);
417 clk_register_clkdev(clk, "sphyclk_div", "mmp-ccic.0");
418
419 clk = mmp_clk_register_apmu("ccic0_sphy", "ccic0_sphy_div",
420 apmu_base + APMU_CCIC0, 0x300, &clk_lock);
421 clk_register_clkdev(clk, "sphyclk", "mmp-ccic.0");
422
423 clk = clk_register_mux(NULL, "ccic1_mux", ccic_parent,
424 ARRAY_SIZE(ccic_parent), CLK_SET_RATE_PARENT,
425 apmu_base + APMU_CCIC1, 6, 2, 0, &clk_lock);
426 clk_register_clkdev(clk, "ccic_mux.1", NULL);
427
428 clk = clk_register_divider(NULL, "ccic1_div", "ccic1_mux",
429 CLK_SET_RATE_PARENT, apmu_base + APMU_CCIC1,
430 16, 4, CLK_DIVIDER_ONE_BASED, &clk_lock);
431 clk_register_clkdev(clk, "ccic_div.1", NULL);
432
433 clk = mmp_clk_register_apmu("ccic1", "ccic1_div",
434 apmu_base + APMU_CCIC1, 0x1b, &clk_lock);
435 clk_register_clkdev(clk, "fnclk", "mmp-ccic.1");
436
437 clk = mmp_clk_register_apmu("ccic1_phy", "ccic1_div",
438 apmu_base + APMU_CCIC1, 0x24, &clk_lock);
439 clk_register_clkdev(clk, "phyclk", "mmp-ccic.1");
440
441 clk = clk_register_divider(NULL, "ccic1_sphy_div", "ccic1_div",
442 CLK_SET_RATE_PARENT, apmu_base + APMU_CCIC1,
443 10, 5, 0, &clk_lock);
444 clk_register_clkdev(clk, "sphyclk_div", "mmp-ccic.1");
445
446 clk = mmp_clk_register_apmu("ccic1_sphy", "ccic1_sphy_div",
447 apmu_base + APMU_CCIC1, 0x300, &clk_lock);
448 clk_register_clkdev(clk, "sphyclk", "mmp-ccic.1");
449}
diff --git a/drivers/clk/mmp/clk-pxa168.c b/drivers/clk/mmp/clk-pxa168.c
new file mode 100644
index 000000000000..e8d036c12cbf
--- /dev/null
+++ b/drivers/clk/mmp/clk-pxa168.c
@@ -0,0 +1,346 @@
1/*
2 * pxa168 clock framework source file
3 *
4 * Copyright (C) 2012 Marvell
5 * Chao Xie <xiechao.mail@gmail.com>
6 *
7 * This file is licensed under the terms of the GNU General Public
8 * License version 2. This program is licensed "as is" without any
9 * warranty of any kind, whether express or implied.
10 */
11
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/spinlock.h>
15#include <linux/io.h>
16#include <linux/delay.h>
17#include <linux/err.h>
18
19#include <mach/addr-map.h>
20
21#include "clk.h"
22
23#define APBC_RTC 0x28
24#define APBC_TWSI0 0x2c
25#define APBC_KPC 0x30
26#define APBC_UART0 0x0
27#define APBC_UART1 0x4
28#define APBC_GPIO 0x8
29#define APBC_PWM0 0xc
30#define APBC_PWM1 0x10
31#define APBC_PWM2 0x14
32#define APBC_PWM3 0x18
33#define APBC_SSP0 0x81c
34#define APBC_SSP1 0x820
35#define APBC_SSP2 0x84c
36#define APBC_SSP3 0x858
37#define APBC_SSP4 0x85c
38#define APBC_TWSI1 0x6c
39#define APBC_UART2 0x70
40#define APMU_SDH0 0x54
41#define APMU_SDH1 0x58
42#define APMU_USB 0x5c
43#define APMU_DISP0 0x4c
44#define APMU_CCIC0 0x50
45#define APMU_DFC 0x60
46#define MPMU_UART_PLL 0x14
47
48static DEFINE_SPINLOCK(clk_lock);
49
50static struct clk_factor_masks uart_factor_masks = {
51 .factor = 2,
52 .num_mask = 0x1fff,
53 .den_mask = 0x1fff,
54 .num_shift = 16,
55 .den_shift = 0,
56};
57
58static struct clk_factor_tbl uart_factor_tbl[] = {
59 {.num = 8125, .den = 1536}, /*14.745MHZ */
60};
61
62static const char *uart_parent[] = {"pll1_3_16", "uart_pll"};
63static const char *ssp_parent[] = {"pll1_96", "pll1_48", "pll1_24", "pll1_12"};
64static const char *sdh_parent[] = {"pll1_12", "pll1_13"};
65static const char *disp_parent[] = {"pll1_2", "pll1_12"};
66static const char *ccic_parent[] = {"pll1_2", "pll1_12"};
67static const char *ccic_phy_parent[] = {"pll1_6", "pll1_12"};
68
69void __init pxa168_clk_init(void)
70{
71 struct clk *clk;
72 struct clk *uart_pll;
73 void __iomem *mpmu_base;
74 void __iomem *apmu_base;
75 void __iomem *apbc_base;
76
77 mpmu_base = ioremap(APB_PHYS_BASE + 0x50000, SZ_4K);
78 if (mpmu_base == NULL) {
79 pr_err("error to ioremap MPMU base\n");
80 return;
81 }
82
83 apmu_base = ioremap(AXI_PHYS_BASE + 0x82800, SZ_4K);
84 if (apmu_base == NULL) {
85 pr_err("error to ioremap APMU base\n");
86 return;
87 }
88
89 apbc_base = ioremap(APB_PHYS_BASE + 0x15000, SZ_4K);
90 if (apbc_base == NULL) {
91 pr_err("error to ioremap APBC base\n");
92 return;
93 }
94
95 clk = clk_register_fixed_rate(NULL, "clk32", NULL, CLK_IS_ROOT, 3200);
96 clk_register_clkdev(clk, "clk32", NULL);
97
98 clk = clk_register_fixed_rate(NULL, "vctcxo", NULL, CLK_IS_ROOT,
99 26000000);
100 clk_register_clkdev(clk, "vctcxo", NULL);
101
102 clk = clk_register_fixed_rate(NULL, "pll1", NULL, CLK_IS_ROOT,
103 624000000);
104 clk_register_clkdev(clk, "pll1", NULL);
105
106 clk = clk_register_fixed_factor(NULL, "pll1_2", "pll1",
107 CLK_SET_RATE_PARENT, 1, 2);
108 clk_register_clkdev(clk, "pll1_2", NULL);
109
110 clk = clk_register_fixed_factor(NULL, "pll1_4", "pll1_2",
111 CLK_SET_RATE_PARENT, 1, 2);
112 clk_register_clkdev(clk, "pll1_4", NULL);
113
114 clk = clk_register_fixed_factor(NULL, "pll1_8", "pll1_4",
115 CLK_SET_RATE_PARENT, 1, 2);
116 clk_register_clkdev(clk, "pll1_8", NULL);
117
118 clk = clk_register_fixed_factor(NULL, "pll1_16", "pll1_8",
119 CLK_SET_RATE_PARENT, 1, 2);
120 clk_register_clkdev(clk, "pll1_16", NULL);
121
122 clk = clk_register_fixed_factor(NULL, "pll1_6", "pll1_2",
123 CLK_SET_RATE_PARENT, 1, 3);
124 clk_register_clkdev(clk, "pll1_6", NULL);
125
126 clk = clk_register_fixed_factor(NULL, "pll1_12", "pll1_6",
127 CLK_SET_RATE_PARENT, 1, 2);
128 clk_register_clkdev(clk, "pll1_12", NULL);
129
130 clk = clk_register_fixed_factor(NULL, "pll1_24", "pll1_12",
131 CLK_SET_RATE_PARENT, 1, 2);
132 clk_register_clkdev(clk, "pll1_24", NULL);
133
134 clk = clk_register_fixed_factor(NULL, "pll1_48", "pll1_24",
135 CLK_SET_RATE_PARENT, 1, 2);
136 clk_register_clkdev(clk, "pll1_48", NULL);
137
138 clk = clk_register_fixed_factor(NULL, "pll1_96", "pll1_48",
139 CLK_SET_RATE_PARENT, 1, 2);
140 clk_register_clkdev(clk, "pll1_96", NULL);
141
142 clk = clk_register_fixed_factor(NULL, "pll1_13", "pll1",
143 CLK_SET_RATE_PARENT, 1, 13);
144 clk_register_clkdev(clk, "pll1_13", NULL);
145
146 clk = clk_register_fixed_factor(NULL, "pll1_13_1_5", "pll1",
147 CLK_SET_RATE_PARENT, 2, 3);
148 clk_register_clkdev(clk, "pll1_13_1_5", NULL);
149
150 clk = clk_register_fixed_factor(NULL, "pll1_2_1_5", "pll1",
151 CLK_SET_RATE_PARENT, 2, 3);
152 clk_register_clkdev(clk, "pll1_2_1_5", NULL);
153
154 clk = clk_register_fixed_factor(NULL, "pll1_3_16", "pll1",
155 CLK_SET_RATE_PARENT, 3, 16);
156 clk_register_clkdev(clk, "pll1_3_16", NULL);
157
158 uart_pll = mmp_clk_register_factor("uart_pll", "pll1_4", 0,
159 mpmu_base + MPMU_UART_PLL,
160 &uart_factor_masks, uart_factor_tbl,
161 ARRAY_SIZE(uart_factor_tbl));
162 clk_set_rate(uart_pll, 14745600);
163 clk_register_clkdev(uart_pll, "uart_pll", NULL);
164
165 clk = mmp_clk_register_apbc("twsi0", "pll1_13_1_5",
166 apbc_base + APBC_TWSI0, 10, 0, &clk_lock);
167 clk_register_clkdev(clk, NULL, "pxa2xx-i2c.0");
168
169 clk = mmp_clk_register_apbc("twsi1", "pll1_13_1_5",
170 apbc_base + APBC_TWSI1, 10, 0, &clk_lock);
171 clk_register_clkdev(clk, NULL, "pxa2xx-i2c.1");
172
173 clk = mmp_clk_register_apbc("gpio", "vctcxo",
174 apbc_base + APBC_GPIO, 10, 0, &clk_lock);
175 clk_register_clkdev(clk, NULL, "pxa-gpio");
176
177 clk = mmp_clk_register_apbc("kpc", "clk32",
178 apbc_base + APBC_KPC, 10, 0, &clk_lock);
179 clk_register_clkdev(clk, NULL, "pxa27x-keypad");
180
181 clk = mmp_clk_register_apbc("rtc", "clk32",
182 apbc_base + APBC_RTC, 10, 0, &clk_lock);
183 clk_register_clkdev(clk, NULL, "sa1100-rtc");
184
185 clk = mmp_clk_register_apbc("pwm0", "pll1_48",
186 apbc_base + APBC_PWM0, 10, 0, &clk_lock);
187 clk_register_clkdev(clk, NULL, "pxa168-pwm.0");
188
189 clk = mmp_clk_register_apbc("pwm1", "pll1_48",
190 apbc_base + APBC_PWM1, 10, 0, &clk_lock);
191 clk_register_clkdev(clk, NULL, "pxa168-pwm.1");
192
193 clk = mmp_clk_register_apbc("pwm2", "pll1_48",
194 apbc_base + APBC_PWM2, 10, 0, &clk_lock);
195 clk_register_clkdev(clk, NULL, "pxa168-pwm.2");
196
197 clk = mmp_clk_register_apbc("pwm3", "pll1_48",
198 apbc_base + APBC_PWM3, 10, 0, &clk_lock);
199 clk_register_clkdev(clk, NULL, "pxa168-pwm.3");
200
201 clk = clk_register_mux(NULL, "uart0_mux", uart_parent,
202 ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
203 apbc_base + APBC_UART0, 4, 3, 0, &clk_lock);
204 clk_set_parent(clk, uart_pll);
205 clk_register_clkdev(clk, "uart_mux.0", NULL);
206
207 clk = mmp_clk_register_apbc("uart0", "uart0_mux",
208 apbc_base + APBC_UART0, 10, 0, &clk_lock);
209 clk_register_clkdev(clk, NULL, "pxa2xx-uart.0");
210
211 clk = clk_register_mux(NULL, "uart1_mux", uart_parent,
212 ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
213 apbc_base + APBC_UART1, 4, 3, 0, &clk_lock);
214 clk_set_parent(clk, uart_pll);
215 clk_register_clkdev(clk, "uart_mux.1", NULL);
216
217 clk = mmp_clk_register_apbc("uart1", "uart1_mux",
218 apbc_base + APBC_UART1, 10, 0, &clk_lock);
219 clk_register_clkdev(clk, NULL, "pxa2xx-uart.1");
220
221 clk = clk_register_mux(NULL, "uart2_mux", uart_parent,
222 ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
223 apbc_base + APBC_UART2, 4, 3, 0, &clk_lock);
224 clk_set_parent(clk, uart_pll);
225 clk_register_clkdev(clk, "uart_mux.2", NULL);
226
227 clk = mmp_clk_register_apbc("uart2", "uart2_mux",
228 apbc_base + APBC_UART2, 10, 0, &clk_lock);
229 clk_register_clkdev(clk, NULL, "pxa2xx-uart.2");
230
231 clk = clk_register_mux(NULL, "ssp0_mux", ssp_parent,
232 ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT,
233 apbc_base + APBC_SSP0, 4, 3, 0, &clk_lock);
234 clk_register_clkdev(clk, "uart_mux.0", NULL);
235
236 clk = mmp_clk_register_apbc("ssp0", "ssp0_mux", apbc_base + APBC_SSP0,
237 10, 0, &clk_lock);
238 clk_register_clkdev(clk, NULL, "mmp-ssp.0");
239
240 clk = clk_register_mux(NULL, "ssp1_mux", ssp_parent,
241 ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT,
242 apbc_base + APBC_SSP1, 4, 3, 0, &clk_lock);
243 clk_register_clkdev(clk, "ssp_mux.1", NULL);
244
245 clk = mmp_clk_register_apbc("ssp1", "ssp1_mux", apbc_base + APBC_SSP1,
246 10, 0, &clk_lock);
247 clk_register_clkdev(clk, NULL, "mmp-ssp.1");
248
249 clk = clk_register_mux(NULL, "ssp2_mux", ssp_parent,
250 ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT,
251 apbc_base + APBC_SSP2, 4, 3, 0, &clk_lock);
252 clk_register_clkdev(clk, "ssp_mux.2", NULL);
253
254 clk = mmp_clk_register_apbc("ssp2", "ssp1_mux", apbc_base + APBC_SSP2,
255 10, 0, &clk_lock);
256 clk_register_clkdev(clk, NULL, "mmp-ssp.2");
257
258 clk = clk_register_mux(NULL, "ssp3_mux", ssp_parent,
259 ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT,
260 apbc_base + APBC_SSP3, 4, 3, 0, &clk_lock);
261 clk_register_clkdev(clk, "ssp_mux.3", NULL);
262
263 clk = mmp_clk_register_apbc("ssp3", "ssp1_mux", apbc_base + APBC_SSP3,
264 10, 0, &clk_lock);
265 clk_register_clkdev(clk, NULL, "mmp-ssp.3");
266
267 clk = clk_register_mux(NULL, "ssp4_mux", ssp_parent,
268 ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT,
269 apbc_base + APBC_SSP4, 4, 3, 0, &clk_lock);
270 clk_register_clkdev(clk, "ssp_mux.4", NULL);
271
272 clk = mmp_clk_register_apbc("ssp4", "ssp1_mux", apbc_base + APBC_SSP4,
273 10, 0, &clk_lock);
274 clk_register_clkdev(clk, NULL, "mmp-ssp.4");
275
276 clk = mmp_clk_register_apmu("dfc", "pll1_4", apmu_base + APMU_DFC,
277 0x19b, &clk_lock);
278 clk_register_clkdev(clk, NULL, "pxa3xx-nand.0");
279
280 clk = clk_register_mux(NULL, "sdh0_mux", sdh_parent,
281 ARRAY_SIZE(sdh_parent), CLK_SET_RATE_PARENT,
282 apmu_base + APMU_SDH0, 6, 1, 0, &clk_lock);
283 clk_register_clkdev(clk, "sdh0_mux", NULL);
284
285 clk = mmp_clk_register_apmu("sdh0", "sdh_mux", apmu_base + APMU_SDH0,
286 0x1b, &clk_lock);
287 clk_register_clkdev(clk, NULL, "sdhci-pxa.0");
288
289 clk = clk_register_mux(NULL, "sdh1_mux", sdh_parent,
290 ARRAY_SIZE(sdh_parent), CLK_SET_RATE_PARENT,
291 apmu_base + APMU_SDH1, 6, 1, 0, &clk_lock);
292 clk_register_clkdev(clk, "sdh1_mux", NULL);
293
294 clk = mmp_clk_register_apmu("sdh1", "sdh1_mux", apmu_base + APMU_SDH1,
295 0x1b, &clk_lock);
296 clk_register_clkdev(clk, NULL, "sdhci-pxa.1");
297
298 clk = mmp_clk_register_apmu("usb", "usb_pll", apmu_base + APMU_USB,
299 0x9, &clk_lock);
300 clk_register_clkdev(clk, "usb_clk", NULL);
301
302 clk = mmp_clk_register_apmu("sph", "usb_pll", apmu_base + APMU_USB,
303 0x12, &clk_lock);
304 clk_register_clkdev(clk, "sph_clk", NULL);
305
306 clk = clk_register_mux(NULL, "disp0_mux", disp_parent,
307 ARRAY_SIZE(disp_parent), CLK_SET_RATE_PARENT,
308 apmu_base + APMU_DISP0, 6, 1, 0, &clk_lock);
309 clk_register_clkdev(clk, "disp_mux.0", NULL);
310
311 clk = mmp_clk_register_apmu("disp0", "disp0_mux",
312 apmu_base + APMU_DISP0, 0x1b, &clk_lock);
313 clk_register_clkdev(clk, "fnclk", "mmp-disp.0");
314
315 clk = mmp_clk_register_apmu("disp0_hclk", "disp0_mux",
316 apmu_base + APMU_DISP0, 0x24, &clk_lock);
317 clk_register_clkdev(clk, "hclk", "mmp-disp.0");
318
319 clk = clk_register_mux(NULL, "ccic0_mux", ccic_parent,
320 ARRAY_SIZE(ccic_parent), CLK_SET_RATE_PARENT,
321 apmu_base + APMU_CCIC0, 6, 1, 0, &clk_lock);
322 clk_register_clkdev(clk, "ccic_mux.0", NULL);
323
324 clk = mmp_clk_register_apmu("ccic0", "ccic0_mux",
325 apmu_base + APMU_CCIC0, 0x1b, &clk_lock);
326 clk_register_clkdev(clk, "fnclk", "mmp-ccic.0");
327
328 clk = clk_register_mux(NULL, "ccic0_phy_mux", ccic_phy_parent,
329 ARRAY_SIZE(ccic_phy_parent),
330 CLK_SET_RATE_PARENT, apmu_base + APMU_CCIC0,
331 7, 1, 0, &clk_lock);
332 clk_register_clkdev(clk, "ccic_phy_mux.0", NULL);
333
334 clk = mmp_clk_register_apmu("ccic0_phy", "ccic0_phy_mux",
335 apmu_base + APMU_CCIC0, 0x24, &clk_lock);
336 clk_register_clkdev(clk, "phyclk", "mmp-ccic.0");
337
338 clk = clk_register_divider(NULL, "ccic0_sphy_div", "ccic0_mux",
339 CLK_SET_RATE_PARENT, apmu_base + APMU_CCIC0,
340 10, 5, 0, &clk_lock);
341 clk_register_clkdev(clk, "sphyclk_div", NULL);
342
343 clk = mmp_clk_register_apmu("ccic0_sphy", "ccic0_sphy_div",
344 apmu_base + APMU_CCIC0, 0x300, &clk_lock);
345 clk_register_clkdev(clk, "sphyclk", "mmp-ccic.0");
346}
diff --git a/drivers/clk/mmp/clk-pxa910.c b/drivers/clk/mmp/clk-pxa910.c
new file mode 100644
index 000000000000..7048c31d6e7e
--- /dev/null
+++ b/drivers/clk/mmp/clk-pxa910.c
@@ -0,0 +1,320 @@
1/*
2 * pxa910 clock framework source file
3 *
4 * Copyright (C) 2012 Marvell
5 * Chao Xie <xiechao.mail@gmail.com>
6 *
7 * This file is licensed under the terms of the GNU General Public
8 * License version 2. This program is licensed "as is" without any
9 * warranty of any kind, whether express or implied.
10 */
11
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/spinlock.h>
15#include <linux/io.h>
16#include <linux/delay.h>
17#include <linux/err.h>
18
19#include <mach/addr-map.h>
20
21#include "clk.h"
22
23#define APBC_RTC 0x28
24#define APBC_TWSI0 0x2c
25#define APBC_KPC 0x18
26#define APBC_UART0 0x0
27#define APBC_UART1 0x4
28#define APBC_GPIO 0x8
29#define APBC_PWM0 0xc
30#define APBC_PWM1 0x10
31#define APBC_PWM2 0x14
32#define APBC_PWM3 0x18
33#define APBC_SSP0 0x1c
34#define APBC_SSP1 0x20
35#define APBC_SSP2 0x4c
36#define APBCP_TWSI1 0x28
37#define APBCP_UART2 0x1c
38#define APMU_SDH0 0x54
39#define APMU_SDH1 0x58
40#define APMU_USB 0x5c
41#define APMU_DISP0 0x4c
42#define APMU_CCIC0 0x50
43#define APMU_DFC 0x60
44#define MPMU_UART_PLL 0x14
45
46static DEFINE_SPINLOCK(clk_lock);
47
48static struct clk_factor_masks uart_factor_masks = {
49 .factor = 2,
50 .num_mask = 0x1fff,
51 .den_mask = 0x1fff,
52 .num_shift = 16,
53 .den_shift = 0,
54};
55
56static struct clk_factor_tbl uart_factor_tbl[] = {
57 {.num = 8125, .den = 1536}, /*14.745MHZ */
58};
59
60static const char *uart_parent[] = {"pll1_3_16", "uart_pll"};
61static const char *ssp_parent[] = {"pll1_96", "pll1_48", "pll1_24", "pll1_12"};
62static const char *sdh_parent[] = {"pll1_12", "pll1_13"};
63static const char *disp_parent[] = {"pll1_2", "pll1_12"};
64static const char *ccic_parent[] = {"pll1_2", "pll1_12"};
65static const char *ccic_phy_parent[] = {"pll1_6", "pll1_12"};
66
67void __init pxa910_clk_init(void)
68{
69 struct clk *clk;
70 struct clk *uart_pll;
71 void __iomem *mpmu_base;
72 void __iomem *apmu_base;
73 void __iomem *apbcp_base;
74 void __iomem *apbc_base;
75
76 mpmu_base = ioremap(APB_PHYS_BASE + 0x50000, SZ_4K);
77 if (mpmu_base == NULL) {
78 pr_err("error to ioremap MPMU base\n");
79 return;
80 }
81
82 apmu_base = ioremap(AXI_PHYS_BASE + 0x82800, SZ_4K);
83 if (apmu_base == NULL) {
84 pr_err("error to ioremap APMU base\n");
85 return;
86 }
87
88 apbcp_base = ioremap(APB_PHYS_BASE + 0x3b000, SZ_4K);
89 if (apbcp_base == NULL) {
90 pr_err("error to ioremap APBC extension base\n");
91 return;
92 }
93
94 apbc_base = ioremap(APB_PHYS_BASE + 0x15000, SZ_4K);
95 if (apbc_base == NULL) {
96 pr_err("error to ioremap APBC base\n");
97 return;
98 }
99
100 clk = clk_register_fixed_rate(NULL, "clk32", NULL, CLK_IS_ROOT, 3200);
101 clk_register_clkdev(clk, "clk32", NULL);
102
103 clk = clk_register_fixed_rate(NULL, "vctcxo", NULL, CLK_IS_ROOT,
104 26000000);
105 clk_register_clkdev(clk, "vctcxo", NULL);
106
107 clk = clk_register_fixed_rate(NULL, "pll1", NULL, CLK_IS_ROOT,
108 624000000);
109 clk_register_clkdev(clk, "pll1", NULL);
110
111 clk = clk_register_fixed_factor(NULL, "pll1_2", "pll1",
112 CLK_SET_RATE_PARENT, 1, 2);
113 clk_register_clkdev(clk, "pll1_2", NULL);
114
115 clk = clk_register_fixed_factor(NULL, "pll1_4", "pll1_2",
116 CLK_SET_RATE_PARENT, 1, 2);
117 clk_register_clkdev(clk, "pll1_4", NULL);
118
119 clk = clk_register_fixed_factor(NULL, "pll1_8", "pll1_4",
120 CLK_SET_RATE_PARENT, 1, 2);
121 clk_register_clkdev(clk, "pll1_8", NULL);
122
123 clk = clk_register_fixed_factor(NULL, "pll1_16", "pll1_8",
124 CLK_SET_RATE_PARENT, 1, 2);
125 clk_register_clkdev(clk, "pll1_16", NULL);
126
127 clk = clk_register_fixed_factor(NULL, "pll1_6", "pll1_2",
128 CLK_SET_RATE_PARENT, 1, 3);
129 clk_register_clkdev(clk, "pll1_6", NULL);
130
131 clk = clk_register_fixed_factor(NULL, "pll1_12", "pll1_6",
132 CLK_SET_RATE_PARENT, 1, 2);
133 clk_register_clkdev(clk, "pll1_12", NULL);
134
135 clk = clk_register_fixed_factor(NULL, "pll1_24", "pll1_12",
136 CLK_SET_RATE_PARENT, 1, 2);
137 clk_register_clkdev(clk, "pll1_24", NULL);
138
139 clk = clk_register_fixed_factor(NULL, "pll1_48", "pll1_24",
140 CLK_SET_RATE_PARENT, 1, 2);
141 clk_register_clkdev(clk, "pll1_48", NULL);
142
143 clk = clk_register_fixed_factor(NULL, "pll1_96", "pll1_48",
144 CLK_SET_RATE_PARENT, 1, 2);
145 clk_register_clkdev(clk, "pll1_96", NULL);
146
147 clk = clk_register_fixed_factor(NULL, "pll1_13", "pll1",
148 CLK_SET_RATE_PARENT, 1, 13);
149 clk_register_clkdev(clk, "pll1_13", NULL);
150
151 clk = clk_register_fixed_factor(NULL, "pll1_13_1_5", "pll1",
152 CLK_SET_RATE_PARENT, 2, 3);
153 clk_register_clkdev(clk, "pll1_13_1_5", NULL);
154
155 clk = clk_register_fixed_factor(NULL, "pll1_2_1_5", "pll1",
156 CLK_SET_RATE_PARENT, 2, 3);
157 clk_register_clkdev(clk, "pll1_2_1_5", NULL);
158
159 clk = clk_register_fixed_factor(NULL, "pll1_3_16", "pll1",
160 CLK_SET_RATE_PARENT, 3, 16);
161 clk_register_clkdev(clk, "pll1_3_16", NULL);
162
163 uart_pll = mmp_clk_register_factor("uart_pll", "pll1_4", 0,
164 mpmu_base + MPMU_UART_PLL,
165 &uart_factor_masks, uart_factor_tbl,
166 ARRAY_SIZE(uart_factor_tbl));
167 clk_set_rate(uart_pll, 14745600);
168 clk_register_clkdev(uart_pll, "uart_pll", NULL);
169
170 clk = mmp_clk_register_apbc("twsi0", "pll1_13_1_5",
171 apbc_base + APBC_TWSI0, 10, 0, &clk_lock);
172 clk_register_clkdev(clk, NULL, "pxa2xx-i2c.0");
173
174 clk = mmp_clk_register_apbc("twsi1", "pll1_13_1_5",
175 apbcp_base + APBCP_TWSI1, 10, 0, &clk_lock);
176 clk_register_clkdev(clk, NULL, "pxa2xx-i2c.1");
177
178 clk = mmp_clk_register_apbc("gpio", "vctcxo",
179 apbc_base + APBC_GPIO, 10, 0, &clk_lock);
180 clk_register_clkdev(clk, NULL, "pxa-gpio");
181
182 clk = mmp_clk_register_apbc("kpc", "clk32",
183 apbc_base + APBC_KPC, 10, 0, &clk_lock);
184 clk_register_clkdev(clk, NULL, "pxa27x-keypad");
185
186 clk = mmp_clk_register_apbc("rtc", "clk32",
187 apbc_base + APBC_RTC, 10, 0, &clk_lock);
188 clk_register_clkdev(clk, NULL, "sa1100-rtc");
189
190 clk = mmp_clk_register_apbc("pwm0", "pll1_48",
191 apbc_base + APBC_PWM0, 10, 0, &clk_lock);
192 clk_register_clkdev(clk, NULL, "pxa910-pwm.0");
193
194 clk = mmp_clk_register_apbc("pwm1", "pll1_48",
195 apbc_base + APBC_PWM1, 10, 0, &clk_lock);
196 clk_register_clkdev(clk, NULL, "pxa910-pwm.1");
197
198 clk = mmp_clk_register_apbc("pwm2", "pll1_48",
199 apbc_base + APBC_PWM2, 10, 0, &clk_lock);
200 clk_register_clkdev(clk, NULL, "pxa910-pwm.2");
201
202 clk = mmp_clk_register_apbc("pwm3", "pll1_48",
203 apbc_base + APBC_PWM3, 10, 0, &clk_lock);
204 clk_register_clkdev(clk, NULL, "pxa910-pwm.3");
205
206 clk = clk_register_mux(NULL, "uart0_mux", uart_parent,
207 ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
208 apbc_base + APBC_UART0, 4, 3, 0, &clk_lock);
209 clk_set_parent(clk, uart_pll);
210 clk_register_clkdev(clk, "uart_mux.0", NULL);
211
212 clk = mmp_clk_register_apbc("uart0", "uart0_mux",
213 apbc_base + APBC_UART0, 10, 0, &clk_lock);
214 clk_register_clkdev(clk, NULL, "pxa2xx-uart.0");
215
216 clk = clk_register_mux(NULL, "uart1_mux", uart_parent,
217 ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
218 apbc_base + APBC_UART1, 4, 3, 0, &clk_lock);
219 clk_set_parent(clk, uart_pll);
220 clk_register_clkdev(clk, "uart_mux.1", NULL);
221
222 clk = mmp_clk_register_apbc("uart1", "uart1_mux",
223 apbc_base + APBC_UART1, 10, 0, &clk_lock);
224 clk_register_clkdev(clk, NULL, "pxa2xx-uart.1");
225
226 clk = clk_register_mux(NULL, "uart2_mux", uart_parent,
227 ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
228 apbcp_base + APBCP_UART2, 4, 3, 0, &clk_lock);
229 clk_set_parent(clk, uart_pll);
230 clk_register_clkdev(clk, "uart_mux.2", NULL);
231
232 clk = mmp_clk_register_apbc("uart2", "uart2_mux",
233 apbcp_base + APBCP_UART2, 10, 0, &clk_lock);
234 clk_register_clkdev(clk, NULL, "pxa2xx-uart.2");
235
236 clk = clk_register_mux(NULL, "ssp0_mux", ssp_parent,
237 ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT,
238 apbc_base + APBC_SSP0, 4, 3, 0, &clk_lock);
239 clk_register_clkdev(clk, "uart_mux.0", NULL);
240
241 clk = mmp_clk_register_apbc("ssp0", "ssp0_mux",
242 apbc_base + APBC_SSP0, 10, 0, &clk_lock);
243 clk_register_clkdev(clk, NULL, "mmp-ssp.0");
244
245 clk = clk_register_mux(NULL, "ssp1_mux", ssp_parent,
246 ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT,
247 apbc_base + APBC_SSP1, 4, 3, 0, &clk_lock);
248 clk_register_clkdev(clk, "ssp_mux.1", NULL);
249
250 clk = mmp_clk_register_apbc("ssp1", "ssp1_mux",
251 apbc_base + APBC_SSP1, 10, 0, &clk_lock);
252 clk_register_clkdev(clk, NULL, "mmp-ssp.1");
253
254 clk = mmp_clk_register_apmu("dfc", "pll1_4",
255 apmu_base + APMU_DFC, 0x19b, &clk_lock);
256 clk_register_clkdev(clk, NULL, "pxa3xx-nand.0");
257
258 clk = clk_register_mux(NULL, "sdh0_mux", sdh_parent,
259 ARRAY_SIZE(sdh_parent), CLK_SET_RATE_PARENT,
260 apmu_base + APMU_SDH0, 6, 1, 0, &clk_lock);
261 clk_register_clkdev(clk, "sdh0_mux", NULL);
262
263 clk = mmp_clk_register_apmu("sdh0", "sdh_mux",
264 apmu_base + APMU_SDH0, 0x1b, &clk_lock);
265 clk_register_clkdev(clk, NULL, "sdhci-pxa.0");
266
267 clk = clk_register_mux(NULL, "sdh1_mux", sdh_parent,
268 ARRAY_SIZE(sdh_parent), CLK_SET_RATE_PARENT,
269 apmu_base + APMU_SDH1, 6, 1, 0, &clk_lock);
270 clk_register_clkdev(clk, "sdh1_mux", NULL);
271
272 clk = mmp_clk_register_apmu("sdh1", "sdh1_mux",
273 apmu_base + APMU_SDH1, 0x1b, &clk_lock);
274 clk_register_clkdev(clk, NULL, "sdhci-pxa.1");
275
276 clk = mmp_clk_register_apmu("usb", "usb_pll",
277 apmu_base + APMU_USB, 0x9, &clk_lock);
278 clk_register_clkdev(clk, "usb_clk", NULL);
279
280 clk = mmp_clk_register_apmu("sph", "usb_pll",
281 apmu_base + APMU_USB, 0x12, &clk_lock);
282 clk_register_clkdev(clk, "sph_clk", NULL);
283
284 clk = clk_register_mux(NULL, "disp0_mux", disp_parent,
285 ARRAY_SIZE(disp_parent), CLK_SET_RATE_PARENT,
286 apmu_base + APMU_DISP0, 6, 1, 0, &clk_lock);
287 clk_register_clkdev(clk, "disp_mux.0", NULL);
288
289 clk = mmp_clk_register_apmu("disp0", "disp0_mux",
290 apmu_base + APMU_DISP0, 0x1b, &clk_lock);
291 clk_register_clkdev(clk, NULL, "mmp-disp.0");
292
293 clk = clk_register_mux(NULL, "ccic0_mux", ccic_parent,
294 ARRAY_SIZE(ccic_parent), CLK_SET_RATE_PARENT,
295 apmu_base + APMU_CCIC0, 6, 1, 0, &clk_lock);
296 clk_register_clkdev(clk, "ccic_mux.0", NULL);
297
298 clk = mmp_clk_register_apmu("ccic0", "ccic0_mux",
299 apmu_base + APMU_CCIC0, 0x1b, &clk_lock);
300 clk_register_clkdev(clk, "fnclk", "mmp-ccic.0");
301
302 clk = clk_register_mux(NULL, "ccic0_phy_mux", ccic_phy_parent,
303 ARRAY_SIZE(ccic_phy_parent),
304 CLK_SET_RATE_PARENT, apmu_base + APMU_CCIC0,
305 7, 1, 0, &clk_lock);
306 clk_register_clkdev(clk, "ccic_phy_mux.0", NULL);
307
308 clk = mmp_clk_register_apmu("ccic0_phy", "ccic0_phy_mux",
309 apmu_base + APMU_CCIC0, 0x24, &clk_lock);
310 clk_register_clkdev(clk, "phyclk", "mmp-ccic.0");
311
312 clk = clk_register_divider(NULL, "ccic0_sphy_div", "ccic0_mux",
313 CLK_SET_RATE_PARENT, apmu_base + APMU_CCIC0,
314 10, 5, 0, &clk_lock);
315 clk_register_clkdev(clk, "sphyclk_div", NULL);
316
317 clk = mmp_clk_register_apmu("ccic0_sphy", "ccic0_sphy_div",
318 apmu_base + APMU_CCIC0, 0x300, &clk_lock);
319 clk_register_clkdev(clk, "sphyclk", "mmp-ccic.0");
320}
diff --git a/drivers/clk/mmp/clk.h b/drivers/clk/mmp/clk.h
new file mode 100644
index 000000000000..ab86dd4a416a
--- /dev/null
+++ b/drivers/clk/mmp/clk.h
@@ -0,0 +1,35 @@
1#ifndef __MACH_MMP_CLK_H
2#define __MACH_MMP_CLK_H
3
4#include <linux/clk-provider.h>
5#include <linux/clkdev.h>
6
7#define APBC_NO_BUS_CTRL BIT(0)
8#define APBC_POWER_CTRL BIT(1)
9
10struct clk_factor_masks {
11 unsigned int factor;
12 unsigned int num_mask;
13 unsigned int den_mask;
14 unsigned int num_shift;
15 unsigned int den_shift;
16};
17
18struct clk_factor_tbl {
19 unsigned int num;
20 unsigned int den;
21};
22
23extern struct clk *mmp_clk_register_pll2(const char *name,
24 const char *parent_name, unsigned long flags);
25extern struct clk *mmp_clk_register_apbc(const char *name,
26 const char *parent_name, void __iomem *base,
27 unsigned int delay, unsigned int apbc_flags, spinlock_t *lock);
28extern struct clk *mmp_clk_register_apmu(const char *name,
29 const char *parent_name, void __iomem *base, u32 enable_mask,
30 spinlock_t *lock);
31extern struct clk *mmp_clk_register_factor(const char *name,
32 const char *parent_name, unsigned long flags,
33 void __iomem *base, struct clk_factor_masks *masks,
34 struct clk_factor_tbl *ftbl, unsigned int ftbl_cnt);
35#endif
diff --git a/drivers/clk/ux500/Makefile b/drivers/clk/ux500/Makefile
new file mode 100644
index 000000000000..858fbfe66281
--- /dev/null
+++ b/drivers/clk/ux500/Makefile
@@ -0,0 +1,12 @@
1#
2# Makefile for ux500 clocks
3#
4
5# Clock types
6obj-y += clk-prcc.o
7obj-y += clk-prcmu.o
8
9# Clock definitions
10obj-y += u8500_clk.o
11obj-y += u9540_clk.o
12obj-y += u8540_clk.o
diff --git a/drivers/clk/ux500/clk-prcc.c b/drivers/clk/ux500/clk-prcc.c
new file mode 100644
index 000000000000..7eee7f768355
--- /dev/null
+++ b/drivers/clk/ux500/clk-prcc.c
@@ -0,0 +1,164 @@
1/*
2 * PRCC clock implementation for ux500 platform.
3 *
4 * Copyright (C) 2012 ST-Ericsson SA
5 * Author: Ulf Hansson <ulf.hansson@linaro.org>
6 *
7 * License terms: GNU General Public License (GPL) version 2
8 */
9
10#include <linux/clk-provider.h>
11#include <linux/clk-private.h>
12#include <linux/slab.h>
13#include <linux/io.h>
14#include <linux/err.h>
15#include <linux/types.h>
16#include <mach/hardware.h>
17
18#include "clk.h"
19
20#define PRCC_PCKEN 0x000
21#define PRCC_PCKDIS 0x004
22#define PRCC_KCKEN 0x008
23#define PRCC_KCKDIS 0x00C
24#define PRCC_PCKSR 0x010
25#define PRCC_KCKSR 0x014
26
27#define to_clk_prcc(_hw) container_of(_hw, struct clk_prcc, hw)
28
29struct clk_prcc {
30 struct clk_hw hw;
31 void __iomem *base;
32 u32 cg_sel;
33 int is_enabled;
34};
35
36/* PRCC clock operations. */
37
38static int clk_prcc_pclk_enable(struct clk_hw *hw)
39{
40 struct clk_prcc *clk = to_clk_prcc(hw);
41
42 writel(clk->cg_sel, (clk->base + PRCC_PCKEN));
43 while (!(readl(clk->base + PRCC_PCKSR) & clk->cg_sel))
44 cpu_relax();
45
46 clk->is_enabled = 1;
47 return 0;
48}
49
50static void clk_prcc_pclk_disable(struct clk_hw *hw)
51{
52 struct clk_prcc *clk = to_clk_prcc(hw);
53
54 writel(clk->cg_sel, (clk->base + PRCC_PCKDIS));
55 clk->is_enabled = 0;
56}
57
58static int clk_prcc_kclk_enable(struct clk_hw *hw)
59{
60 struct clk_prcc *clk = to_clk_prcc(hw);
61
62 writel(clk->cg_sel, (clk->base + PRCC_KCKEN));
63 while (!(readl(clk->base + PRCC_KCKSR) & clk->cg_sel))
64 cpu_relax();
65
66 clk->is_enabled = 1;
67 return 0;
68}
69
70static void clk_prcc_kclk_disable(struct clk_hw *hw)
71{
72 struct clk_prcc *clk = to_clk_prcc(hw);
73
74 writel(clk->cg_sel, (clk->base + PRCC_KCKDIS));
75 clk->is_enabled = 0;
76}
77
78static int clk_prcc_is_enabled(struct clk_hw *hw)
79{
80 struct clk_prcc *clk = to_clk_prcc(hw);
81 return clk->is_enabled;
82}
83
84static struct clk_ops clk_prcc_pclk_ops = {
85 .enable = clk_prcc_pclk_enable,
86 .disable = clk_prcc_pclk_disable,
87 .is_enabled = clk_prcc_is_enabled,
88};
89
90static struct clk_ops clk_prcc_kclk_ops = {
91 .enable = clk_prcc_kclk_enable,
92 .disable = clk_prcc_kclk_disable,
93 .is_enabled = clk_prcc_is_enabled,
94};
95
96static struct clk *clk_reg_prcc(const char *name,
97 const char *parent_name,
98 resource_size_t phy_base,
99 u32 cg_sel,
100 unsigned long flags,
101 struct clk_ops *clk_prcc_ops)
102{
103 struct clk_prcc *clk;
104 struct clk_init_data clk_prcc_init;
105 struct clk *clk_reg;
106
107 if (!name) {
108 pr_err("clk_prcc: %s invalid arguments passed\n", __func__);
109 return ERR_PTR(-EINVAL);
110 }
111
112 clk = kzalloc(sizeof(struct clk_prcc), GFP_KERNEL);
113 if (!clk) {
114 pr_err("clk_prcc: %s could not allocate clk\n", __func__);
115 return ERR_PTR(-ENOMEM);
116 }
117
118 clk->base = ioremap(phy_base, SZ_4K);
119 if (!clk->base)
120 goto free_clk;
121
122 clk->cg_sel = cg_sel;
123 clk->is_enabled = 1;
124
125 clk_prcc_init.name = name;
126 clk_prcc_init.ops = clk_prcc_ops;
127 clk_prcc_init.flags = flags;
128 clk_prcc_init.parent_names = (parent_name ? &parent_name : NULL);
129 clk_prcc_init.num_parents = (parent_name ? 1 : 0);
130 clk->hw.init = &clk_prcc_init;
131
132 clk_reg = clk_register(NULL, &clk->hw);
133 if (IS_ERR_OR_NULL(clk_reg))
134 goto unmap_clk;
135
136 return clk_reg;
137
138unmap_clk:
139 iounmap(clk->base);
140free_clk:
141 kfree(clk);
142 pr_err("clk_prcc: %s failed to register clk\n", __func__);
143 return ERR_PTR(-ENOMEM);
144}
145
146struct clk *clk_reg_prcc_pclk(const char *name,
147 const char *parent_name,
148 resource_size_t phy_base,
149 u32 cg_sel,
150 unsigned long flags)
151{
152 return clk_reg_prcc(name, parent_name, phy_base, cg_sel, flags,
153 &clk_prcc_pclk_ops);
154}
155
156struct clk *clk_reg_prcc_kclk(const char *name,
157 const char *parent_name,
158 resource_size_t phy_base,
159 u32 cg_sel,
160 unsigned long flags)
161{
162 return clk_reg_prcc(name, parent_name, phy_base, cg_sel, flags,
163 &clk_prcc_kclk_ops);
164}
diff --git a/drivers/clk/ux500/clk-prcmu.c b/drivers/clk/ux500/clk-prcmu.c
new file mode 100644
index 000000000000..930cdfeb47ab
--- /dev/null
+++ b/drivers/clk/ux500/clk-prcmu.c
@@ -0,0 +1,252 @@
1/*
2 * PRCMU clock implementation for ux500 platform.
3 *
4 * Copyright (C) 2012 ST-Ericsson SA
5 * Author: Ulf Hansson <ulf.hansson@linaro.org>
6 *
7 * License terms: GNU General Public License (GPL) version 2
8 */
9
10#include <linux/clk-provider.h>
11#include <linux/clk-private.h>
12#include <linux/mfd/dbx500-prcmu.h>
13#include <linux/slab.h>
14#include <linux/io.h>
15#include <linux/err.h>
16#include "clk.h"
17
18#define to_clk_prcmu(_hw) container_of(_hw, struct clk_prcmu, hw)
19
20struct clk_prcmu {
21 struct clk_hw hw;
22 u8 cg_sel;
23 int is_enabled;
24};
25
26/* PRCMU clock operations. */
27
28static int clk_prcmu_prepare(struct clk_hw *hw)
29{
30 struct clk_prcmu *clk = to_clk_prcmu(hw);
31 return prcmu_request_clock(clk->cg_sel, true);
32}
33
34static void clk_prcmu_unprepare(struct clk_hw *hw)
35{
36 struct clk_prcmu *clk = to_clk_prcmu(hw);
37 if (prcmu_request_clock(clk->cg_sel, false))
38 pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
39 hw->init->name);
40}
41
42static int clk_prcmu_enable(struct clk_hw *hw)
43{
44 struct clk_prcmu *clk = to_clk_prcmu(hw);
45 clk->is_enabled = 1;
46 return 0;
47}
48
49static void clk_prcmu_disable(struct clk_hw *hw)
50{
51 struct clk_prcmu *clk = to_clk_prcmu(hw);
52 clk->is_enabled = 0;
53}
54
55static int clk_prcmu_is_enabled(struct clk_hw *hw)
56{
57 struct clk_prcmu *clk = to_clk_prcmu(hw);
58 return clk->is_enabled;
59}
60
61static unsigned long clk_prcmu_recalc_rate(struct clk_hw *hw,
62 unsigned long parent_rate)
63{
64 struct clk_prcmu *clk = to_clk_prcmu(hw);
65 return prcmu_clock_rate(clk->cg_sel);
66}
67
68static long clk_prcmu_round_rate(struct clk_hw *hw, unsigned long rate,
69 unsigned long *parent_rate)
70{
71 struct clk_prcmu *clk = to_clk_prcmu(hw);
72 return prcmu_round_clock_rate(clk->cg_sel, rate);
73}
74
75static int clk_prcmu_set_rate(struct clk_hw *hw, unsigned long rate,
76 unsigned long parent_rate)
77{
78 struct clk_prcmu *clk = to_clk_prcmu(hw);
79 return prcmu_set_clock_rate(clk->cg_sel, rate);
80}
81
82static int request_ape_opp100(bool enable)
83{
84 static int reqs;
85 int err = 0;
86
87 if (enable) {
88 if (!reqs)
89 err = prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP,
90 "clock", 100);
91 if (!err)
92 reqs++;
93 } else {
94 reqs--;
95 if (!reqs)
96 prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP,
97 "clock");
98 }
99 return err;
100}
101
102static int clk_prcmu_opp_prepare(struct clk_hw *hw)
103{
104 int err;
105 struct clk_prcmu *clk = to_clk_prcmu(hw);
106
107 err = request_ape_opp100(true);
108 if (err) {
109 pr_err("clk_prcmu: %s failed to request APE OPP100 for %s.\n",
110 __func__, hw->init->name);
111 return err;
112 }
113
114 err = prcmu_request_clock(clk->cg_sel, true);
115 if (err)
116 request_ape_opp100(false);
117
118 return err;
119}
120
121static void clk_prcmu_opp_unprepare(struct clk_hw *hw)
122{
123 struct clk_prcmu *clk = to_clk_prcmu(hw);
124
125 if (prcmu_request_clock(clk->cg_sel, false))
126 goto out_error;
127 if (request_ape_opp100(false))
128 goto out_error;
129 return;
130
131out_error:
132 pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
133 hw->init->name);
134}
135
136static struct clk_ops clk_prcmu_scalable_ops = {
137 .prepare = clk_prcmu_prepare,
138 .unprepare = clk_prcmu_unprepare,
139 .enable = clk_prcmu_enable,
140 .disable = clk_prcmu_disable,
141 .is_enabled = clk_prcmu_is_enabled,
142 .recalc_rate = clk_prcmu_recalc_rate,
143 .round_rate = clk_prcmu_round_rate,
144 .set_rate = clk_prcmu_set_rate,
145};
146
147static struct clk_ops clk_prcmu_gate_ops = {
148 .prepare = clk_prcmu_prepare,
149 .unprepare = clk_prcmu_unprepare,
150 .enable = clk_prcmu_enable,
151 .disable = clk_prcmu_disable,
152 .is_enabled = clk_prcmu_is_enabled,
153 .recalc_rate = clk_prcmu_recalc_rate,
154};
155
156static struct clk_ops clk_prcmu_rate_ops = {
157 .is_enabled = clk_prcmu_is_enabled,
158 .recalc_rate = clk_prcmu_recalc_rate,
159};
160
161static struct clk_ops clk_prcmu_opp_gate_ops = {
162 .prepare = clk_prcmu_opp_prepare,
163 .unprepare = clk_prcmu_opp_unprepare,
164 .enable = clk_prcmu_enable,
165 .disable = clk_prcmu_disable,
166 .is_enabled = clk_prcmu_is_enabled,
167 .recalc_rate = clk_prcmu_recalc_rate,
168};
169
170static struct clk *clk_reg_prcmu(const char *name,
171 const char *parent_name,
172 u8 cg_sel,
173 unsigned long rate,
174 unsigned long flags,
175 struct clk_ops *clk_prcmu_ops)
176{
177 struct clk_prcmu *clk;
178 struct clk_init_data clk_prcmu_init;
179 struct clk *clk_reg;
180
181 if (!name) {
182 pr_err("clk_prcmu: %s invalid arguments passed\n", __func__);
183 return ERR_PTR(-EINVAL);
184 }
185
186 clk = kzalloc(sizeof(struct clk_prcmu), GFP_KERNEL);
187 if (!clk) {
188 pr_err("clk_prcmu: %s could not allocate clk\n", __func__);
189 return ERR_PTR(-ENOMEM);
190 }
191
192 clk->cg_sel = cg_sel;
193 clk->is_enabled = 1;
194 /* "rate" can be used for changing the initial frequency */
195 if (rate)
196 prcmu_set_clock_rate(cg_sel, rate);
197
198 clk_prcmu_init.name = name;
199 clk_prcmu_init.ops = clk_prcmu_ops;
200 clk_prcmu_init.flags = flags;
201 clk_prcmu_init.parent_names = (parent_name ? &parent_name : NULL);
202 clk_prcmu_init.num_parents = (parent_name ? 1 : 0);
203 clk->hw.init = &clk_prcmu_init;
204
205 clk_reg = clk_register(NULL, &clk->hw);
206 if (IS_ERR_OR_NULL(clk_reg))
207 goto free_clk;
208
209 return clk_reg;
210
211free_clk:
212 kfree(clk);
213 pr_err("clk_prcmu: %s failed to register clk\n", __func__);
214 return ERR_PTR(-ENOMEM);
215}
216
217struct clk *clk_reg_prcmu_scalable(const char *name,
218 const char *parent_name,
219 u8 cg_sel,
220 unsigned long rate,
221 unsigned long flags)
222{
223 return clk_reg_prcmu(name, parent_name, cg_sel, rate, flags,
224 &clk_prcmu_scalable_ops);
225}
226
227struct clk *clk_reg_prcmu_gate(const char *name,
228 const char *parent_name,
229 u8 cg_sel,
230 unsigned long flags)
231{
232 return clk_reg_prcmu(name, parent_name, cg_sel, 0, flags,
233 &clk_prcmu_gate_ops);
234}
235
236struct clk *clk_reg_prcmu_rate(const char *name,
237 const char *parent_name,
238 u8 cg_sel,
239 unsigned long flags)
240{
241 return clk_reg_prcmu(name, parent_name, cg_sel, 0, flags,
242 &clk_prcmu_rate_ops);
243}
244
245struct clk *clk_reg_prcmu_opp_gate(const char *name,
246 const char *parent_name,
247 u8 cg_sel,
248 unsigned long flags)
249{
250 return clk_reg_prcmu(name, parent_name, cg_sel, 0, flags,
251 &clk_prcmu_opp_gate_ops);
252}
diff --git a/drivers/clk/ux500/clk.h b/drivers/clk/ux500/clk.h
new file mode 100644
index 000000000000..836d7d16751e
--- /dev/null
+++ b/drivers/clk/ux500/clk.h
@@ -0,0 +1,48 @@
1/*
2 * Clocks for ux500 platforms
3 *
4 * Copyright (C) 2012 ST-Ericsson SA
5 * Author: Ulf Hansson <ulf.hansson@linaro.org>
6 *
7 * License terms: GNU General Public License (GPL) version 2
8 */
9
10#ifndef __UX500_CLK_H
11#define __UX500_CLK_H
12
13#include <linux/clk.h>
14
15struct clk *clk_reg_prcc_pclk(const char *name,
16 const char *parent_name,
17 unsigned int phy_base,
18 u32 cg_sel,
19 unsigned long flags);
20
21struct clk *clk_reg_prcc_kclk(const char *name,
22 const char *parent_name,
23 unsigned int phy_base,
24 u32 cg_sel,
25 unsigned long flags);
26
27struct clk *clk_reg_prcmu_scalable(const char *name,
28 const char *parent_name,
29 u8 cg_sel,
30 unsigned long rate,
31 unsigned long flags);
32
33struct clk *clk_reg_prcmu_gate(const char *name,
34 const char *parent_name,
35 u8 cg_sel,
36 unsigned long flags);
37
38struct clk *clk_reg_prcmu_rate(const char *name,
39 const char *parent_name,
40 u8 cg_sel,
41 unsigned long flags);
42
43struct clk *clk_reg_prcmu_opp_gate(const char *name,
44 const char *parent_name,
45 u8 cg_sel,
46 unsigned long flags);
47
48#endif /* __UX500_CLK_H */
diff --git a/drivers/clk/ux500/u8500_clk.c b/drivers/clk/ux500/u8500_clk.c
new file mode 100644
index 000000000000..ca4a25ed844c
--- /dev/null
+++ b/drivers/clk/ux500/u8500_clk.c
@@ -0,0 +1,477 @@
1/*
2 * Clock definitions for u8500 platform.
3 *
4 * Copyright (C) 2012 ST-Ericsson SA
5 * Author: Ulf Hansson <ulf.hansson@linaro.org>
6 *
7 * License terms: GNU General Public License (GPL) version 2
8 */
9
10#include <linux/clk.h>
11#include <linux/clkdev.h>
12#include <linux/clk-provider.h>
13#include <linux/mfd/dbx500-prcmu.h>
14#include <linux/platform_data/clk-ux500.h>
15
16#include "clk.h"
17
18void u8500_clk_init(void)
19{
20 struct prcmu_fw_version *fw_version;
21 const char *sgaclk_parent = NULL;
22 struct clk *clk;
23
24 /* Clock sources */
25 clk = clk_reg_prcmu_gate("soc0_pll", NULL, PRCMU_PLLSOC0,
26 CLK_IS_ROOT|CLK_IGNORE_UNUSED);
27 clk_register_clkdev(clk, "soc0_pll", NULL);
28
29 clk = clk_reg_prcmu_gate("soc1_pll", NULL, PRCMU_PLLSOC1,
30 CLK_IS_ROOT|CLK_IGNORE_UNUSED);
31 clk_register_clkdev(clk, "soc1_pll", NULL);
32
33 clk = clk_reg_prcmu_gate("ddr_pll", NULL, PRCMU_PLLDDR,
34 CLK_IS_ROOT|CLK_IGNORE_UNUSED);
35 clk_register_clkdev(clk, "ddr_pll", NULL);
36
37 /* FIXME: Add sys, ulp and int clocks here. */
38
39 clk = clk_register_fixed_rate(NULL, "rtc32k", "NULL",
40 CLK_IS_ROOT|CLK_IGNORE_UNUSED,
41 32768);
42 clk_register_clkdev(clk, "clk32k", NULL);
43 clk_register_clkdev(clk, NULL, "rtc-pl031");
44
45 /* PRCMU clocks */
46 fw_version = prcmu_get_fw_version();
47 if (fw_version != NULL) {
48 switch (fw_version->project) {
49 case PRCMU_FW_PROJECT_U8500_C2:
50 case PRCMU_FW_PROJECT_U8520:
51 case PRCMU_FW_PROJECT_U8420:
52 sgaclk_parent = "soc0_pll";
53 break;
54 default:
55 break;
56 }
57 }
58
59 if (sgaclk_parent)
60 clk = clk_reg_prcmu_gate("sgclk", sgaclk_parent,
61 PRCMU_SGACLK, 0);
62 else
63 clk = clk_reg_prcmu_gate("sgclk", NULL,
64 PRCMU_SGACLK, CLK_IS_ROOT);
65 clk_register_clkdev(clk, NULL, "mali");
66
67 clk = clk_reg_prcmu_gate("uartclk", NULL, PRCMU_UARTCLK, CLK_IS_ROOT);
68 clk_register_clkdev(clk, NULL, "UART");
69
70 clk = clk_reg_prcmu_gate("msp02clk", NULL, PRCMU_MSP02CLK, CLK_IS_ROOT);
71 clk_register_clkdev(clk, NULL, "MSP02");
72
73 clk = clk_reg_prcmu_gate("msp1clk", NULL, PRCMU_MSP1CLK, CLK_IS_ROOT);
74 clk_register_clkdev(clk, NULL, "MSP1");
75
76 clk = clk_reg_prcmu_gate("i2cclk", NULL, PRCMU_I2CCLK, CLK_IS_ROOT);
77 clk_register_clkdev(clk, NULL, "I2C");
78
79 clk = clk_reg_prcmu_gate("slimclk", NULL, PRCMU_SLIMCLK, CLK_IS_ROOT);
80 clk_register_clkdev(clk, NULL, "slim");
81
82 clk = clk_reg_prcmu_gate("per1clk", NULL, PRCMU_PER1CLK, CLK_IS_ROOT);
83 clk_register_clkdev(clk, NULL, "PERIPH1");
84
85 clk = clk_reg_prcmu_gate("per2clk", NULL, PRCMU_PER2CLK, CLK_IS_ROOT);
86 clk_register_clkdev(clk, NULL, "PERIPH2");
87
88 clk = clk_reg_prcmu_gate("per3clk", NULL, PRCMU_PER3CLK, CLK_IS_ROOT);
89 clk_register_clkdev(clk, NULL, "PERIPH3");
90
91 clk = clk_reg_prcmu_gate("per5clk", NULL, PRCMU_PER5CLK, CLK_IS_ROOT);
92 clk_register_clkdev(clk, NULL, "PERIPH5");
93
94 clk = clk_reg_prcmu_gate("per6clk", NULL, PRCMU_PER6CLK, CLK_IS_ROOT);
95 clk_register_clkdev(clk, NULL, "PERIPH6");
96
97 clk = clk_reg_prcmu_gate("per7clk", NULL, PRCMU_PER7CLK, CLK_IS_ROOT);
98 clk_register_clkdev(clk, NULL, "PERIPH7");
99
100 clk = clk_reg_prcmu_scalable("lcdclk", NULL, PRCMU_LCDCLK, 0,
101 CLK_IS_ROOT|CLK_SET_RATE_GATE);
102 clk_register_clkdev(clk, NULL, "lcd");
103 clk_register_clkdev(clk, "lcd", "mcde");
104
105 clk = clk_reg_prcmu_opp_gate("bmlclk", NULL, PRCMU_BMLCLK, CLK_IS_ROOT);
106 clk_register_clkdev(clk, NULL, "bml");
107
108 clk = clk_reg_prcmu_scalable("hsitxclk", NULL, PRCMU_HSITXCLK, 0,
109 CLK_IS_ROOT|CLK_SET_RATE_GATE);
110
111 clk = clk_reg_prcmu_scalable("hsirxclk", NULL, PRCMU_HSIRXCLK, 0,
112 CLK_IS_ROOT|CLK_SET_RATE_GATE);
113
114 clk = clk_reg_prcmu_scalable("hdmiclk", NULL, PRCMU_HDMICLK, 0,
115 CLK_IS_ROOT|CLK_SET_RATE_GATE);
116 clk_register_clkdev(clk, NULL, "hdmi");
117 clk_register_clkdev(clk, "hdmi", "mcde");
118
119 clk = clk_reg_prcmu_gate("apeatclk", NULL, PRCMU_APEATCLK, CLK_IS_ROOT);
120 clk_register_clkdev(clk, NULL, "apeat");
121
122 clk = clk_reg_prcmu_gate("apetraceclk", NULL, PRCMU_APETRACECLK,
123 CLK_IS_ROOT);
124 clk_register_clkdev(clk, NULL, "apetrace");
125
126 clk = clk_reg_prcmu_gate("mcdeclk", NULL, PRCMU_MCDECLK, CLK_IS_ROOT);
127 clk_register_clkdev(clk, NULL, "mcde");
128 clk_register_clkdev(clk, "mcde", "mcde");
129 clk_register_clkdev(clk, "dsisys", "dsilink.0");
130 clk_register_clkdev(clk, "dsisys", "dsilink.1");
131 clk_register_clkdev(clk, "dsisys", "dsilink.2");
132
133 clk = clk_reg_prcmu_opp_gate("ipi2cclk", NULL, PRCMU_IPI2CCLK,
134 CLK_IS_ROOT);
135 clk_register_clkdev(clk, NULL, "ipi2");
136
137 clk = clk_reg_prcmu_gate("dsialtclk", NULL, PRCMU_DSIALTCLK,
138 CLK_IS_ROOT);
139 clk_register_clkdev(clk, NULL, "dsialt");
140
141 clk = clk_reg_prcmu_gate("dmaclk", NULL, PRCMU_DMACLK, CLK_IS_ROOT);
142 clk_register_clkdev(clk, NULL, "dma40.0");
143
144 clk = clk_reg_prcmu_gate("b2r2clk", NULL, PRCMU_B2R2CLK, CLK_IS_ROOT);
145 clk_register_clkdev(clk, NULL, "b2r2");
146 clk_register_clkdev(clk, NULL, "b2r2_core");
147 clk_register_clkdev(clk, NULL, "U8500-B2R2.0");
148
149 clk = clk_reg_prcmu_scalable("tvclk", NULL, PRCMU_TVCLK, 0,
150 CLK_IS_ROOT|CLK_SET_RATE_GATE);
151 clk_register_clkdev(clk, NULL, "tv");
152 clk_register_clkdev(clk, "tv", "mcde");
153
154 clk = clk_reg_prcmu_gate("sspclk", NULL, PRCMU_SSPCLK, CLK_IS_ROOT);
155 clk_register_clkdev(clk, NULL, "SSP");
156
157 clk = clk_reg_prcmu_gate("rngclk", NULL, PRCMU_RNGCLK, CLK_IS_ROOT);
158 clk_register_clkdev(clk, NULL, "rngclk");
159
160 clk = clk_reg_prcmu_gate("uiccclk", NULL, PRCMU_UICCCLK, CLK_IS_ROOT);
161 clk_register_clkdev(clk, NULL, "uicc");
162
163 /*
164 * FIXME: The MTU clocks might need some kind of "parent muxed join"
165 * and these have no K-clocks. For now, we ignore the missing
166 * connection to the corresponding P-clocks, p6_mtu0_clk and
167 * p6_mtu1_clk. Instead timclk is used which is the valid parent.
168 */
169 clk = clk_reg_prcmu_gate("timclk", NULL, PRCMU_TIMCLK, CLK_IS_ROOT);
170 clk_register_clkdev(clk, NULL, "mtu0");
171 clk_register_clkdev(clk, NULL, "mtu1");
172
173 clk = clk_reg_prcmu_gate("sdmmcclk", NULL, PRCMU_SDMMCCLK, CLK_IS_ROOT);
174 clk_register_clkdev(clk, NULL, "sdmmc");
175
176
177 clk = clk_reg_prcmu_scalable("dsi_pll", "hdmiclk",
178 PRCMU_PLLDSI, 0, CLK_SET_RATE_GATE);
179 clk_register_clkdev(clk, "dsihs2", "mcde");
180 clk_register_clkdev(clk, "dsihs2", "dsilink.2");
181
182
183 clk = clk_reg_prcmu_scalable("dsi0clk", "dsi_pll",
184 PRCMU_DSI0CLK, 0, CLK_SET_RATE_GATE);
185 clk_register_clkdev(clk, "dsihs0", "mcde");
186 clk_register_clkdev(clk, "dsihs0", "dsilink.0");
187
188 clk = clk_reg_prcmu_scalable("dsi1clk", "dsi_pll",
189 PRCMU_DSI1CLK, 0, CLK_SET_RATE_GATE);
190 clk_register_clkdev(clk, "dsihs1", "mcde");
191 clk_register_clkdev(clk, "dsihs1", "dsilink.1");
192
193 clk = clk_reg_prcmu_scalable("dsi0escclk", "tvclk",
194 PRCMU_DSI0ESCCLK, 0, CLK_SET_RATE_GATE);
195 clk_register_clkdev(clk, "dsilp0", "dsilink.0");
196 clk_register_clkdev(clk, "dsilp0", "mcde");
197
198 clk = clk_reg_prcmu_scalable("dsi1escclk", "tvclk",
199 PRCMU_DSI1ESCCLK, 0, CLK_SET_RATE_GATE);
200 clk_register_clkdev(clk, "dsilp1", "dsilink.1");
201 clk_register_clkdev(clk, "dsilp1", "mcde");
202
203 clk = clk_reg_prcmu_scalable("dsi2escclk", "tvclk",
204 PRCMU_DSI2ESCCLK, 0, CLK_SET_RATE_GATE);
205 clk_register_clkdev(clk, "dsilp2", "dsilink.2");
206 clk_register_clkdev(clk, "dsilp2", "mcde");
207
208 clk = clk_reg_prcmu_rate("smp_twd", NULL, PRCMU_ARMSS,
209 CLK_IS_ROOT|CLK_GET_RATE_NOCACHE|
210 CLK_IGNORE_UNUSED);
211 clk_register_clkdev(clk, NULL, "smp_twd");
212
213 /*
214 * FIXME: Add special handled PRCMU clocks here:
215 * 1. clk_arm, use PRCMU_ARMCLK.
216 * 2. clkout0yuv, use PRCMU as parent + need regulator + pinctrl.
217 * 3. ab9540_clkout1yuv, see clkout0yuv
218 */
219
220 /* PRCC P-clocks */
221 clk = clk_reg_prcc_pclk("p1_pclk0", "per1clk", U8500_CLKRST1_BASE,
222 BIT(0), 0);
223 clk_register_clkdev(clk, "apb_pclk", "uart0");
224
225 clk = clk_reg_prcc_pclk("p1_pclk1", "per1clk", U8500_CLKRST1_BASE,
226 BIT(1), 0);
227 clk_register_clkdev(clk, "apb_pclk", "uart1");
228
229 clk = clk_reg_prcc_pclk("p1_pclk2", "per1clk", U8500_CLKRST1_BASE,
230 BIT(2), 0);
231 clk = clk_reg_prcc_pclk("p1_pclk3", "per1clk", U8500_CLKRST1_BASE,
232 BIT(3), 0);
233 clk = clk_reg_prcc_pclk("p1_pclk4", "per1clk", U8500_CLKRST1_BASE,
234 BIT(4), 0);
235
236 clk = clk_reg_prcc_pclk("p1_pclk5", "per1clk", U8500_CLKRST1_BASE,
237 BIT(5), 0);
238 clk_register_clkdev(clk, "apb_pclk", "sdi0");
239
240 clk = clk_reg_prcc_pclk("p1_pclk6", "per1clk", U8500_CLKRST1_BASE,
241 BIT(6), 0);
242
243 clk = clk_reg_prcc_pclk("p1_pclk7", "per1clk", U8500_CLKRST1_BASE,
244 BIT(7), 0);
245 clk_register_clkdev(clk, NULL, "spi3");
246
247 clk = clk_reg_prcc_pclk("p1_pclk8", "per1clk", U8500_CLKRST1_BASE,
248 BIT(8), 0);
249
250 clk = clk_reg_prcc_pclk("p1_pclk9", "per1clk", U8500_CLKRST1_BASE,
251 BIT(9), 0);
252 clk_register_clkdev(clk, NULL, "gpio.0");
253 clk_register_clkdev(clk, NULL, "gpio.1");
254 clk_register_clkdev(clk, NULL, "gpioblock0");
255
256 clk = clk_reg_prcc_pclk("p1_pclk10", "per1clk", U8500_CLKRST1_BASE,
257 BIT(10), 0);
258 clk = clk_reg_prcc_pclk("p1_pclk11", "per1clk", U8500_CLKRST1_BASE,
259 BIT(11), 0);
260
261 clk = clk_reg_prcc_pclk("p2_pclk0", "per2clk", U8500_CLKRST2_BASE,
262 BIT(0), 0);
263
264 clk = clk_reg_prcc_pclk("p2_pclk1", "per2clk", U8500_CLKRST2_BASE,
265 BIT(1), 0);
266 clk_register_clkdev(clk, NULL, "spi2");
267
268 clk = clk_reg_prcc_pclk("p2_pclk2", "per2clk", U8500_CLKRST2_BASE,
269 BIT(2), 0);
270 clk_register_clkdev(clk, NULL, "spi1");
271
272 clk = clk_reg_prcc_pclk("p2_pclk3", "per2clk", U8500_CLKRST2_BASE,
273 BIT(3), 0);
274 clk_register_clkdev(clk, NULL, "pwl");
275
276 clk = clk_reg_prcc_pclk("p2_pclk4", "per2clk", U8500_CLKRST2_BASE,
277 BIT(4), 0);
278 clk_register_clkdev(clk, "apb_pclk", "sdi4");
279
280 clk = clk_reg_prcc_pclk("p2_pclk5", "per2clk", U8500_CLKRST2_BASE,
281 BIT(5), 0);
282
283 clk = clk_reg_prcc_pclk("p2_pclk6", "per2clk", U8500_CLKRST2_BASE,
284 BIT(6), 0);
285 clk_register_clkdev(clk, "apb_pclk", "sdi1");
286
287
288 clk = clk_reg_prcc_pclk("p2_pclk7", "per2clk", U8500_CLKRST2_BASE,
289 BIT(7), 0);
290 clk_register_clkdev(clk, "apb_pclk", "sdi3");
291
292 clk = clk_reg_prcc_pclk("p2_pclk8", "per2clk", U8500_CLKRST2_BASE,
293 BIT(8), 0);
294 clk_register_clkdev(clk, NULL, "spi0");
295
296 clk = clk_reg_prcc_pclk("p2_pclk9", "per2clk", U8500_CLKRST2_BASE,
297 BIT(9), 0);
298 clk_register_clkdev(clk, "hsir_hclk", "ste_hsi.0");
299
300 clk = clk_reg_prcc_pclk("p2_pclk10", "per2clk", U8500_CLKRST2_BASE,
301 BIT(10), 0);
302 clk_register_clkdev(clk, "hsit_hclk", "ste_hsi.0");
303
304 clk = clk_reg_prcc_pclk("p2_pclk11", "per2clk", U8500_CLKRST2_BASE,
305 BIT(11), 0);
306 clk_register_clkdev(clk, NULL, "gpio.6");
307 clk_register_clkdev(clk, NULL, "gpio.7");
308 clk_register_clkdev(clk, NULL, "gpioblock1");
309
310 clk = clk_reg_prcc_pclk("p2_pclk12", "per2clk", U8500_CLKRST2_BASE,
311 BIT(11), 0);
312
313 clk = clk_reg_prcc_pclk("p3_pclk0", "per3clk", U8500_CLKRST3_BASE,
314 BIT(0), 0);
315 clk_register_clkdev(clk, NULL, "fsmc");
316
317 clk = clk_reg_prcc_pclk("p3_pclk1", "per3clk", U8500_CLKRST3_BASE,
318 BIT(1), 0);
319 clk = clk_reg_prcc_pclk("p3_pclk2", "per3clk", U8500_CLKRST3_BASE,
320 BIT(2), 0);
321 clk = clk_reg_prcc_pclk("p3_pclk3", "per3clk", U8500_CLKRST3_BASE,
322 BIT(3), 0);
323
324 clk = clk_reg_prcc_pclk("p3_pclk4", "per3clk", U8500_CLKRST3_BASE,
325 BIT(4), 0);
326 clk_register_clkdev(clk, "apb_pclk", "sdi2");
327
328 clk = clk_reg_prcc_pclk("p3_pclk5", "per3clk", U8500_CLKRST3_BASE,
329 BIT(5), 0);
330
331 clk = clk_reg_prcc_pclk("p3_pclk6", "per3clk", U8500_CLKRST3_BASE,
332 BIT(6), 0);
333 clk_register_clkdev(clk, "apb_pclk", "uart2");
334
335 clk = clk_reg_prcc_pclk("p3_pclk7", "per3clk", U8500_CLKRST3_BASE,
336 BIT(7), 0);
337 clk_register_clkdev(clk, "apb_pclk", "sdi5");
338
339 clk = clk_reg_prcc_pclk("p3_pclk8", "per3clk", U8500_CLKRST3_BASE,
340 BIT(8), 0);
341 clk_register_clkdev(clk, NULL, "gpio.2");
342 clk_register_clkdev(clk, NULL, "gpio.3");
343 clk_register_clkdev(clk, NULL, "gpio.4");
344 clk_register_clkdev(clk, NULL, "gpio.5");
345 clk_register_clkdev(clk, NULL, "gpioblock2");
346
347 clk = clk_reg_prcc_pclk("p5_pclk0", "per5clk", U8500_CLKRST5_BASE,
348 BIT(0), 0);
349 clk_register_clkdev(clk, "usb", "musb-ux500.0");
350
351 clk = clk_reg_prcc_pclk("p5_pclk1", "per5clk", U8500_CLKRST5_BASE,
352 BIT(1), 0);
353 clk_register_clkdev(clk, NULL, "gpio.8");
354 clk_register_clkdev(clk, NULL, "gpioblock3");
355
356 clk = clk_reg_prcc_pclk("p6_pclk0", "per6clk", U8500_CLKRST6_BASE,
357 BIT(0), 0);
358
359 clk = clk_reg_prcc_pclk("p6_pclk1", "per6clk", U8500_CLKRST6_BASE,
360 BIT(1), 0);
361 clk_register_clkdev(clk, NULL, "cryp0");
362 clk_register_clkdev(clk, NULL, "cryp1");
363
364 clk = clk_reg_prcc_pclk("p6_pclk2", "per6clk", U8500_CLKRST6_BASE,
365 BIT(2), 0);
366 clk_register_clkdev(clk, NULL, "hash0");
367
368 clk = clk_reg_prcc_pclk("p6_pclk3", "per6clk", U8500_CLKRST6_BASE,
369 BIT(3), 0);
370 clk_register_clkdev(clk, NULL, "pka");
371
372 clk = clk_reg_prcc_pclk("p6_pclk4", "per6clk", U8500_CLKRST6_BASE,
373 BIT(4), 0);
374 clk_register_clkdev(clk, NULL, "hash1");
375
376 clk = clk_reg_prcc_pclk("p6_pclk5", "per6clk", U8500_CLKRST6_BASE,
377 BIT(5), 0);
378 clk_register_clkdev(clk, NULL, "cfgreg");
379
380 clk = clk_reg_prcc_pclk("p6_pclk6", "per6clk", U8500_CLKRST6_BASE,
381 BIT(6), 0);
382 clk = clk_reg_prcc_pclk("p6_pclk7", "per6clk", U8500_CLKRST6_BASE,
383 BIT(7), 0);
384
385 /* PRCC K-clocks
386 *
387 * FIXME: Some drivers requires PERPIH[n| to be automatically enabled
388 * by enabling just the K-clock, even if it is not a valid parent to
389 * the K-clock. Until drivers get fixed we might need some kind of
390 * "parent muxed join".
391 */
392
393 /* Periph1 */
394 clk = clk_reg_prcc_kclk("p1_uart0_kclk", "uartclk",
395 U8500_CLKRST1_BASE, BIT(0), CLK_SET_RATE_GATE);
396 clk_register_clkdev(clk, NULL, "uart0");
397
398 clk = clk_reg_prcc_kclk("p1_uart1_kclk", "uartclk",
399 U8500_CLKRST1_BASE, BIT(1), CLK_SET_RATE_GATE);
400 clk_register_clkdev(clk, NULL, "uart1");
401
402 clk = clk_reg_prcc_kclk("p1_i2c1_kclk", "i2cclk",
403 U8500_CLKRST1_BASE, BIT(2), CLK_SET_RATE_GATE);
404 clk = clk_reg_prcc_kclk("p1_msp0_kclk", "msp02clk",
405 U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE);
406 clk = clk_reg_prcc_kclk("p1_msp1_kclk", "msp1clk",
407 U8500_CLKRST1_BASE, BIT(4), CLK_SET_RATE_GATE);
408
409 clk = clk_reg_prcc_kclk("p1_sdi0_kclk", "sdmmcclk",
410 U8500_CLKRST1_BASE, BIT(5), CLK_SET_RATE_GATE);
411 clk_register_clkdev(clk, NULL, "sdi0");
412
413 clk = clk_reg_prcc_kclk("p1_i2c2_kclk", "i2cclk",
414 U8500_CLKRST1_BASE, BIT(6), CLK_SET_RATE_GATE);
415 clk = clk_reg_prcc_kclk("p1_slimbus0_kclk", "slimclk",
416 U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE);
417 /* FIXME: Redefinition of BIT(3). */
418 clk = clk_reg_prcc_kclk("p1_i2c4_kclk", "i2cclk",
419 U8500_CLKRST1_BASE, BIT(9), CLK_SET_RATE_GATE);
420 clk = clk_reg_prcc_kclk("p1_msp3_kclk", "msp1clk",
421 U8500_CLKRST1_BASE, BIT(10), CLK_SET_RATE_GATE);
422
423 /* Periph2 */
424 clk = clk_reg_prcc_kclk("p2_i2c3_kclk", "i2cclk",
425 U8500_CLKRST2_BASE, BIT(0), CLK_SET_RATE_GATE);
426
427 clk = clk_reg_prcc_kclk("p2_sdi4_kclk", "sdmmcclk",
428 U8500_CLKRST2_BASE, BIT(2), CLK_SET_RATE_GATE);
429 clk_register_clkdev(clk, NULL, "sdi4");
430
431 clk = clk_reg_prcc_kclk("p2_msp2_kclk", "msp02clk",
432 U8500_CLKRST2_BASE, BIT(3), CLK_SET_RATE_GATE);
433
434 clk = clk_reg_prcc_kclk("p2_sdi1_kclk", "sdmmcclk",
435 U8500_CLKRST2_BASE, BIT(4), CLK_SET_RATE_GATE);
436 clk_register_clkdev(clk, NULL, "sdi1");
437
438 clk = clk_reg_prcc_kclk("p2_sdi3_kclk", "sdmmcclk",
439 U8500_CLKRST2_BASE, BIT(5), CLK_SET_RATE_GATE);
440 clk_register_clkdev(clk, NULL, "sdi3");
441
442 /* Note that rate is received from parent. */
443 clk = clk_reg_prcc_kclk("p2_ssirx_kclk", "hsirxclk",
444 U8500_CLKRST2_BASE, BIT(6),
445 CLK_SET_RATE_GATE|CLK_SET_RATE_PARENT);
446 clk = clk_reg_prcc_kclk("p2_ssitx_kclk", "hsitxclk",
447 U8500_CLKRST2_BASE, BIT(7),
448 CLK_SET_RATE_GATE|CLK_SET_RATE_PARENT);
449
450 /* Periph3 */
451 clk = clk_reg_prcc_kclk("p3_ssp0_kclk", "sspclk",
452 U8500_CLKRST3_BASE, BIT(1), CLK_SET_RATE_GATE);
453 clk = clk_reg_prcc_kclk("p3_ssp1_kclk", "sspclk",
454 U8500_CLKRST3_BASE, BIT(2), CLK_SET_RATE_GATE);
455 clk = clk_reg_prcc_kclk("p3_i2c0_kclk", "i2cclk",
456 U8500_CLKRST3_BASE, BIT(3), CLK_SET_RATE_GATE);
457
458 clk = clk_reg_prcc_kclk("p3_sdi2_kclk", "sdmmcclk",
459 U8500_CLKRST3_BASE, BIT(4), CLK_SET_RATE_GATE);
460 clk_register_clkdev(clk, NULL, "sdi2");
461
462 clk = clk_reg_prcc_kclk("p3_ske_kclk", "rtc32k",
463 U8500_CLKRST3_BASE, BIT(5), CLK_SET_RATE_GATE);
464
465 clk = clk_reg_prcc_kclk("p3_uart2_kclk", "uartclk",
466 U8500_CLKRST3_BASE, BIT(6), CLK_SET_RATE_GATE);
467 clk_register_clkdev(clk, NULL, "uart2");
468
469 clk = clk_reg_prcc_kclk("p3_sdi5_kclk", "sdmmcclk",
470 U8500_CLKRST3_BASE, BIT(7), CLK_SET_RATE_GATE);
471 clk_register_clkdev(clk, NULL, "sdi5");
472
473 /* Periph6 */
474 clk = clk_reg_prcc_kclk("p3_rng_kclk", "rngclk",
475 U8500_CLKRST6_BASE, BIT(0), CLK_SET_RATE_GATE);
476
477}
diff --git a/drivers/clk/ux500/u8540_clk.c b/drivers/clk/ux500/u8540_clk.c
new file mode 100644
index 000000000000..10adfd2ead21
--- /dev/null
+++ b/drivers/clk/ux500/u8540_clk.c
@@ -0,0 +1,21 @@
1/*
2 * Clock definitions for u8540 platform.
3 *
4 * Copyright (C) 2012 ST-Ericsson SA
5 * Author: Ulf Hansson <ulf.hansson@linaro.org>
6 *
7 * License terms: GNU General Public License (GPL) version 2
8 */
9
10#include <linux/clk.h>
11#include <linux/clkdev.h>
12#include <linux/clk-provider.h>
13#include <linux/mfd/dbx500-prcmu.h>
14#include <linux/platform_data/clk-ux500.h>
15
16#include "clk.h"
17
18void u8540_clk_init(void)
19{
20 /* register clocks here */
21}
diff --git a/drivers/clk/ux500/u9540_clk.c b/drivers/clk/ux500/u9540_clk.c
new file mode 100644
index 000000000000..dbc0191e16c8
--- /dev/null
+++ b/drivers/clk/ux500/u9540_clk.c
@@ -0,0 +1,21 @@
1/*
2 * Clock definitions for u9540 platform.
3 *
4 * Copyright (C) 2012 ST-Ericsson SA
5 * Author: Ulf Hansson <ulf.hansson@linaro.org>
6 *
7 * License terms: GNU General Public License (GPL) version 2
8 */
9
10#include <linux/clk.h>
11#include <linux/clkdev.h>
12#include <linux/clk-provider.h>
13#include <linux/mfd/dbx500-prcmu.h>
14#include <linux/platform_data/clk-ux500.h>
15
16#include "clk.h"
17
18void u9540_clk_init(void)
19{
20 /* register clocks here */
21}
diff --git a/drivers/clk/versatile/Makefile b/drivers/clk/versatile/Makefile
index 50cf6a2ee693..c0a0f6478798 100644
--- a/drivers/clk/versatile/Makefile
+++ b/drivers/clk/versatile/Makefile
@@ -1,3 +1,4 @@
1# Makefile for Versatile-specific clocks 1# Makefile for Versatile-specific clocks
2obj-$(CONFIG_ICST) += clk-icst.o 2obj-$(CONFIG_ICST) += clk-icst.o
3obj-$(CONFIG_ARCH_INTEGRATOR) += clk-integrator.o 3obj-$(CONFIG_ARCH_INTEGRATOR) += clk-integrator.o
4obj-$(CONFIG_ARCH_REALVIEW) += clk-realview.o
diff --git a/drivers/clk/versatile/clk-realview.c b/drivers/clk/versatile/clk-realview.c
new file mode 100644
index 000000000000..e21a99cef378
--- /dev/null
+++ b/drivers/clk/versatile/clk-realview.c
@@ -0,0 +1,114 @@
1#include <linux/clk.h>
2#include <linux/clkdev.h>
3#include <linux/err.h>
4#include <linux/io.h>
5#include <linux/clk-provider.h>
6
7#include <mach/hardware.h>
8#include <mach/platform.h>
9
10#include "clk-icst.h"
11
12/*
13 * Implementation of the ARM RealView clock trees.
14 */
15
16static void __iomem *sys_lock;
17static void __iomem *sys_vcoreg;
18
19/**
20 * realview_oscvco_get() - get ICST OSC settings for the RealView
21 */
22static struct icst_vco realview_oscvco_get(void)
23{
24 u32 val;
25 struct icst_vco vco;
26
27 val = readl(sys_vcoreg);
28 vco.v = val & 0x1ff;
29 vco.r = (val >> 9) & 0x7f;
30 vco.s = (val >> 16) & 03;
31 return vco;
32}
33
34static void realview_oscvco_set(struct icst_vco vco)
35{
36 u32 val;
37
38 val = readl(sys_vcoreg) & ~0x7ffff;
39 val |= vco.v | (vco.r << 9) | (vco.s << 16);
40
41 /* This magic unlocks the CM VCO so it can be controlled */
42 writel(0xa05f, sys_lock);
43 writel(val, sys_vcoreg);
44 /* This locks the CM again */
45 writel(0, sys_lock);
46}
47
48static const struct icst_params realview_oscvco_params = {
49 .ref = 24000000,
50 .vco_max = ICST307_VCO_MAX,
51 .vco_min = ICST307_VCO_MIN,
52 .vd_min = 4 + 8,
53 .vd_max = 511 + 8,
54 .rd_min = 1 + 2,
55 .rd_max = 127 + 2,
56 .s2div = icst307_s2div,
57 .idx2s = icst307_idx2s,
58};
59
60static const struct clk_icst_desc __initdata realview_icst_desc = {
61 .params = &realview_oscvco_params,
62 .getvco = realview_oscvco_get,
63 .setvco = realview_oscvco_set,
64};
65
66/*
67 * realview_clk_init() - set up the RealView clock tree
68 */
69void __init realview_clk_init(void __iomem *sysbase, bool is_pb1176)
70{
71 struct clk *clk;
72
73 sys_lock = sysbase + REALVIEW_SYS_LOCK_OFFSET;
74 if (is_pb1176)
75 sys_vcoreg = sysbase + REALVIEW_SYS_OSC0_OFFSET;
76 else
77 sys_vcoreg = sysbase + REALVIEW_SYS_OSC4_OFFSET;
78
79
80 /* APB clock dummy */
81 clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, 0);
82 clk_register_clkdev(clk, "apb_pclk", NULL);
83
84 /* 24 MHz clock */
85 clk = clk_register_fixed_rate(NULL, "clk24mhz", NULL, CLK_IS_ROOT,
86 24000000);
87 clk_register_clkdev(clk, NULL, "dev:uart0");
88 clk_register_clkdev(clk, NULL, "dev:uart1");
89 clk_register_clkdev(clk, NULL, "dev:uart2");
90 clk_register_clkdev(clk, NULL, "fpga:kmi0");
91 clk_register_clkdev(clk, NULL, "fpga:kmi1");
92 clk_register_clkdev(clk, NULL, "fpga:mmc0");
93 clk_register_clkdev(clk, NULL, "dev:ssp0");
94 if (is_pb1176) {
95 /*
96 * UART3 is on the dev chip in PB1176
97 * UART4 only exists in PB1176
98 */
99 clk_register_clkdev(clk, NULL, "dev:uart3");
100 clk_register_clkdev(clk, NULL, "dev:uart4");
101 } else
102 clk_register_clkdev(clk, NULL, "fpga:uart3");
103
104
105 /* 1 MHz clock */
106 clk = clk_register_fixed_rate(NULL, "clk1mhz", NULL, CLK_IS_ROOT,
107 1000000);
108 clk_register_clkdev(clk, NULL, "sp804");
109
110 /* ICST VCO clock */
111 clk = icst_clk_register(NULL, &realview_icst_desc);
112 clk_register_clkdev(clk, NULL, "dev:clcd");
113 clk_register_clkdev(clk, NULL, "issp:clcd");
114}
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c
index 0e63cdd9b52a..6b67edbdbd01 100644
--- a/drivers/mfd/db8500-prcmu.c
+++ b/drivers/mfd/db8500-prcmu.c
@@ -418,6 +418,9 @@ static struct {
418 418
419static atomic_t ac_wake_req_state = ATOMIC_INIT(0); 419static atomic_t ac_wake_req_state = ATOMIC_INIT(0);
420 420
421/* Functions definition */
422static void compute_armss_rate(void);
423
421/* Spinlocks */ 424/* Spinlocks */
422static DEFINE_SPINLOCK(prcmu_lock); 425static DEFINE_SPINLOCK(prcmu_lock);
423static DEFINE_SPINLOCK(clkout_lock); 426static DEFINE_SPINLOCK(clkout_lock);
@@ -517,6 +520,7 @@ static struct dsiescclk dsiescclk[3] = {
517 } 520 }
518}; 521};
519 522
523
520/* 524/*
521* Used by MCDE to setup all necessary PRCMU registers 525* Used by MCDE to setup all necessary PRCMU registers
522*/ 526*/
@@ -1013,6 +1017,7 @@ int db8500_prcmu_set_arm_opp(u8 opp)
1013 (mb1_transfer.ack.arm_opp != opp)) 1017 (mb1_transfer.ack.arm_opp != opp))
1014 r = -EIO; 1018 r = -EIO;
1015 1019
1020 compute_armss_rate();
1016 mutex_unlock(&mb1_transfer.lock); 1021 mutex_unlock(&mb1_transfer.lock);
1017 1022
1018 return r; 1023 return r;
@@ -1612,6 +1617,7 @@ static unsigned long pll_rate(void __iomem *reg, unsigned long src_rate,
1612 if ((branch == PLL_FIX) || ((branch == PLL_DIV) && 1617 if ((branch == PLL_FIX) || ((branch == PLL_DIV) &&
1613 (val & PRCM_PLL_FREQ_DIV2EN) && 1618 (val & PRCM_PLL_FREQ_DIV2EN) &&
1614 ((reg == PRCM_PLLSOC0_FREQ) || 1619 ((reg == PRCM_PLLSOC0_FREQ) ||
1620 (reg == PRCM_PLLARM_FREQ) ||
1615 (reg == PRCM_PLLDDR_FREQ)))) 1621 (reg == PRCM_PLLDDR_FREQ))))
1616 div *= 2; 1622 div *= 2;
1617 1623
@@ -1661,6 +1667,39 @@ static unsigned long clock_rate(u8 clock)
1661 else 1667 else
1662 return 0; 1668 return 0;
1663} 1669}
1670static unsigned long latest_armss_rate;
1671static unsigned long armss_rate(void)
1672{
1673 return latest_armss_rate;
1674}
1675
1676static void compute_armss_rate(void)
1677{
1678 u32 r;
1679 unsigned long rate;
1680
1681 r = readl(PRCM_ARM_CHGCLKREQ);
1682
1683 if (r & PRCM_ARM_CHGCLKREQ_PRCM_ARM_CHGCLKREQ) {
1684 /* External ARMCLKFIX clock */
1685
1686 rate = pll_rate(PRCM_PLLDDR_FREQ, ROOT_CLOCK_RATE, PLL_FIX);
1687
1688 /* Check PRCM_ARM_CHGCLKREQ divider */
1689 if (!(r & PRCM_ARM_CHGCLKREQ_PRCM_ARM_DIVSEL))
1690 rate /= 2;
1691
1692 /* Check PRCM_ARMCLKFIX_MGT divider */
1693 r = readl(PRCM_ARMCLKFIX_MGT);
1694 r &= PRCM_CLK_MGT_CLKPLLDIV_MASK;
1695 rate /= r;
1696
1697 } else {/* ARM PLL */
1698 rate = pll_rate(PRCM_PLLARM_FREQ, ROOT_CLOCK_RATE, PLL_DIV);
1699 }
1700
1701 latest_armss_rate = rate;
1702}
1664 1703
1665static unsigned long dsiclk_rate(u8 n) 1704static unsigned long dsiclk_rate(u8 n)
1666{ 1705{
@@ -1707,6 +1746,8 @@ unsigned long prcmu_clock_rate(u8 clock)
1707 return pll_rate(PRCM_PLLSOC0_FREQ, ROOT_CLOCK_RATE, PLL_RAW); 1746 return pll_rate(PRCM_PLLSOC0_FREQ, ROOT_CLOCK_RATE, PLL_RAW);
1708 else if (clock == PRCMU_PLLSOC1) 1747 else if (clock == PRCMU_PLLSOC1)
1709 return pll_rate(PRCM_PLLSOC1_FREQ, ROOT_CLOCK_RATE, PLL_RAW); 1748 return pll_rate(PRCM_PLLSOC1_FREQ, ROOT_CLOCK_RATE, PLL_RAW);
1749 else if (clock == PRCMU_ARMSS)
1750 return armss_rate();
1710 else if (clock == PRCMU_PLLDDR) 1751 else if (clock == PRCMU_PLLDDR)
1711 return pll_rate(PRCM_PLLDDR_FREQ, ROOT_CLOCK_RATE, PLL_RAW); 1752 return pll_rate(PRCM_PLLDDR_FREQ, ROOT_CLOCK_RATE, PLL_RAW);
1712 else if (clock == PRCMU_PLLDSI) 1753 else if (clock == PRCMU_PLLDSI)
@@ -2693,6 +2734,7 @@ void __init db8500_prcmu_early_init(void)
2693 handle_simple_irq); 2734 handle_simple_irq);
2694 set_irq_flags(irq, IRQF_VALID); 2735 set_irq_flags(irq, IRQF_VALID);
2695 } 2736 }
2737 compute_armss_rate();
2696} 2738}
2697 2739
2698static void __init init_prcm_registers(void) 2740static void __init init_prcm_registers(void)
diff --git a/drivers/mfd/dbx500-prcmu-regs.h b/drivers/mfd/dbx500-prcmu-regs.h
index 23108a6e3167..79c76ebdba52 100644
--- a/drivers/mfd/dbx500-prcmu-regs.h
+++ b/drivers/mfd/dbx500-prcmu-regs.h
@@ -61,7 +61,8 @@
61#define PRCM_PLLARM_LOCKP_PRCM_PLLARM_LOCKP3 0x2 61#define PRCM_PLLARM_LOCKP_PRCM_PLLARM_LOCKP3 0x2
62 62
63#define PRCM_ARM_CHGCLKREQ (_PRCMU_BASE + 0x114) 63#define PRCM_ARM_CHGCLKREQ (_PRCMU_BASE + 0x114)
64#define PRCM_ARM_CHGCLKREQ_PRCM_ARM_CHGCLKREQ 0x1 64#define PRCM_ARM_CHGCLKREQ_PRCM_ARM_CHGCLKREQ BIT(0)
65#define PRCM_ARM_CHGCLKREQ_PRCM_ARM_DIVSEL BIT(16)
65 66
66#define PRCM_PLLARM_ENABLE (_PRCMU_BASE + 0x98) 67#define PRCM_PLLARM_ENABLE (_PRCMU_BASE + 0x98)
67#define PRCM_PLLARM_ENABLE_PRCM_PLLARM_ENABLE 0x1 68#define PRCM_PLLARM_ENABLE_PRCM_PLLARM_ENABLE 0x1
@@ -140,6 +141,7 @@
140/* PRCMU clock/PLL/reset registers */ 141/* PRCMU clock/PLL/reset registers */
141#define PRCM_PLLSOC0_FREQ (_PRCMU_BASE + 0x080) 142#define PRCM_PLLSOC0_FREQ (_PRCMU_BASE + 0x080)
142#define PRCM_PLLSOC1_FREQ (_PRCMU_BASE + 0x084) 143#define PRCM_PLLSOC1_FREQ (_PRCMU_BASE + 0x084)
144#define PRCM_PLLARM_FREQ (_PRCMU_BASE + 0x088)
143#define PRCM_PLLDDR_FREQ (_PRCMU_BASE + 0x08C) 145#define PRCM_PLLDDR_FREQ (_PRCMU_BASE + 0x08C)
144#define PRCM_PLL_FREQ_D_SHIFT 0 146#define PRCM_PLL_FREQ_D_SHIFT 0
145#define PRCM_PLL_FREQ_D_MASK BITS(0, 7) 147#define PRCM_PLL_FREQ_D_MASK BITS(0, 7)
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 77335fac943e..c12731582920 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -26,6 +26,7 @@
26#define CLK_IGNORE_UNUSED BIT(3) /* do not gate even if unused */ 26#define CLK_IGNORE_UNUSED BIT(3) /* do not gate even if unused */
27#define CLK_IS_ROOT BIT(4) /* root clk, has no parent */ 27#define CLK_IS_ROOT BIT(4) /* root clk, has no parent */
28#define CLK_IS_BASIC BIT(5) /* Basic clk, can't do a to_clk_foo() */ 28#define CLK_IS_BASIC BIT(5) /* Basic clk, can't do a to_clk_foo() */
29#define CLK_GET_RATE_NOCACHE BIT(6) /* do not use the cached clk rate */
29 30
30struct clk_hw; 31struct clk_hw;
31 32
@@ -360,6 +361,11 @@ int of_clk_add_provider(struct device_node *np,
360void of_clk_del_provider(struct device_node *np); 361void of_clk_del_provider(struct device_node *np);
361struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec, 362struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec,
362 void *data); 363 void *data);
364struct clk_onecell_data {
365 struct clk **clks;
366 unsigned int clk_num;
367};
368struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data);
363const char *of_clk_get_parent_name(struct device_node *np, int index); 369const char *of_clk_get_parent_name(struct device_node *np, int index);
364void of_clk_init(const struct of_device_id *matches); 370void of_clk_init(const struct of_device_id *matches);
365 371
diff --git a/include/linux/mfd/dbx500-prcmu.h b/include/linux/mfd/dbx500-prcmu.h
index 5b90e94399e1..c410d99bd667 100644
--- a/include/linux/mfd/dbx500-prcmu.h
+++ b/include/linux/mfd/dbx500-prcmu.h
@@ -136,6 +136,7 @@ enum prcmu_clock {
136 PRCMU_TIMCLK, 136 PRCMU_TIMCLK,
137 PRCMU_PLLSOC0, 137 PRCMU_PLLSOC0,
138 PRCMU_PLLSOC1, 138 PRCMU_PLLSOC1,
139 PRCMU_ARMSS,
139 PRCMU_PLLDDR, 140 PRCMU_PLLDDR,
140 PRCMU_PLLDSI, 141 PRCMU_PLLDSI,
141 PRCMU_DSI0CLK, 142 PRCMU_DSI0CLK,
diff --git a/include/linux/platform_data/clk-realview.h b/include/linux/platform_data/clk-realview.h
new file mode 100644
index 000000000000..2e426a7dbc51
--- /dev/null
+++ b/include/linux/platform_data/clk-realview.h
@@ -0,0 +1 @@
void realview_clk_init(void __iomem *sysbase, bool is_pb1176);
diff --git a/include/linux/platform_data/clk-ux500.h b/include/linux/platform_data/clk-ux500.h
new file mode 100644
index 000000000000..3af0da1f3be5
--- /dev/null
+++ b/include/linux/platform_data/clk-ux500.h
@@ -0,0 +1,17 @@
1/*
2 * Clock definitions for ux500 platforms
3 *
4 * Copyright (C) 2012 ST-Ericsson SA
5 * Author: Ulf Hansson <ulf.hansson@linaro.org>
6 *
7 * License terms: GNU General Public License (GPL) version 2
8 */
9
10#ifndef __CLK_UX500_H
11#define __CLK_UX500_H
12
13void u8500_clk_init(void);
14void u9540_clk_init(void);
15void u8540_clk_init(void);
16
17#endif /* __CLK_UX500_H */