mach-ux500: crypto - core support for CRYP/HASH module.
[linux-2.6-block.git] / arch / arm / mach-ux500 / clock.c
CommitLineData
c6b503ca
SK
1/*
2 * Copyright (C) 2009 ST-Ericsson
1df20afc 3 * Copyright (C) 2009 STMicroelectronics
c6b503ca
SK
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>
1df20afc 15#include <linux/io.h>
6d803ba7 16#include <linux/clkdev.h>
ef7a474c 17#include <linux/cpufreq.h>
c6b503ca 18
ba327b1e 19#include <plat/mtu.h>
1df20afc
RV
20#include <mach/hardware.h>
21#include "clock.h"
22
763eef8b
VG
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
1df20afc
RV
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
ba327b1e
LW
69#define PRCM_TCR 0x1C8
70#define PRCM_TCR_STOPPED (1 << 16)
71#define PRCM_TCR_DOZE_MODE (1 << 17)
1df20afc
RV
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}
c6b503ca
SK
94
95int clk_enable(struct clk *clk)
96{
1df20afc
RV
97 unsigned long flags;
98
99 spin_lock_irqsave(&clocks_lock, flags);
100 __clk_enable(clk);
101 spin_unlock_irqrestore(&clocks_lock, flags);
102
c6b503ca
SK
103 return 0;
104}
105EXPORT_SYMBOL(clk_enable);
106
1df20afc
RV
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
c6b503ca
SK
121void clk_disable(struct clk *clk)
122{
1df20afc
RV
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);
c6b503ca
SK
130}
131EXPORT_SYMBOL(clk_disable);
132
ba327b1e
LW
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{
92389ca8 140 void __iomem *addr;
f306954c 141 u32 tcr;
ba327b1e
LW
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
92389ca8
RV
152 if (cpu_is_u5500())
153 addr = __io_address(U5500_PRCMU_BASE);
154 else if (cpu_is_u8500())
155 addr = __io_address(U8500_PRCMU_BASE);
156 else
157 ux500_unknown_soc();
158
f306954c
SI
159 /*
160 * On a startup, always conifgure the TCR to the doze mode;
161 * bootloaders do it for us. Do this in the kernel too.
162 */
92389ca8 163 writel(PRCM_TCR_DOZE_MODE, addr + PRCM_TCR);
f306954c 164
92389ca8 165 tcr = readl(addr + PRCM_TCR);
f306954c 166
ba327b1e
LW
167 /* Get the rate from the parent as a default */
168 if (clk->parent_periph)
169 mturate = clk_get_rate(clk->parent_periph);
170 else if (clk->parent_cluster)
171 mturate = clk_get_rate(clk->parent_cluster);
172 else
173 /* We need to be connected SOMEWHERE */
174 BUG();
175
ba327b1e
LW
176 /* Return the clock selected for this MTU */
177 if (tcr & (1 << mtu))
178 retclk = clk32k;
179 else
180 retclk = mturate;
181
182 pr_info("MTU%d clock rate: %lu Hz\n", mtu, retclk);
183 return retclk;
184}
185
c6b503ca
SK
186unsigned long clk_get_rate(struct clk *clk)
187{
1df20afc
RV
188 unsigned long rate;
189
ba327b1e
LW
190 /*
191 * If there is a custom getrate callback for this clock,
192 * it will take precedence.
193 */
194 if (clk->get_rate)
195 return clk->get_rate(clk);
196
1df20afc
RV
197 if (clk->ops && clk->ops->get_rate)
198 return clk->ops->get_rate(clk);
199
200 rate = clk->rate;
201 if (!rate) {
202 if (clk->parent_periph)
203 rate = clk_get_rate(clk->parent_periph);
204 else if (clk->parent_cluster)
205 rate = clk_get_rate(clk->parent_cluster);
206 }
207
208 return rate;
c6b503ca
SK
209}
210EXPORT_SYMBOL(clk_get_rate);
211
212long clk_round_rate(struct clk *clk, unsigned long rate)
213{
214 /*TODO*/
215 return rate;
216}
217EXPORT_SYMBOL(clk_round_rate);
218
219int clk_set_rate(struct clk *clk, unsigned long rate)
220{
221 clk->rate = rate;
222 return 0;
223}
224EXPORT_SYMBOL(clk_set_rate);
225
25cb3b4c
OL
226int clk_set_parent(struct clk *clk, struct clk *parent)
227{
228 /*TODO*/
229 return -ENOSYS;
230}
231EXPORT_SYMBOL(clk_set_parent);
232
1df20afc
RV
233static void clk_prcmu_enable(struct clk *clk)
234{
235 void __iomem *cg_set_reg = __io_address(U8500_PRCMU_BASE)
236 + PRCM_YYCLKEN0_MGT_SET + clk->prcmu_cg_off;
237
238 writel(1 << clk->prcmu_cg_bit, cg_set_reg);
239}
240
241static void clk_prcmu_disable(struct clk *clk)
242{
243 void __iomem *cg_clr_reg = __io_address(U8500_PRCMU_BASE)
244 + PRCM_YYCLKEN0_MGT_CLR + clk->prcmu_cg_off;
245
246 writel(1 << clk->prcmu_cg_bit, cg_clr_reg);
247}
248
1df20afc
RV
249static struct clkops clk_prcmu_ops = {
250 .enable = clk_prcmu_enable,
251 .disable = clk_prcmu_disable,
c6b503ca
SK
252};
253
1df20afc
RV
254static unsigned int clkrst_base[] = {
255 [1] = U8500_CLKRST1_BASE,
256 [2] = U8500_CLKRST2_BASE,
257 [3] = U8500_CLKRST3_BASE,
258 [5] = U8500_CLKRST5_BASE,
259 [6] = U8500_CLKRST6_BASE,
c6b503ca
SK
260};
261
1df20afc
RV
262static void clk_prcc_enable(struct clk *clk)
263{
264 void __iomem *addr = __io_address(clkrst_base[clk->cluster]);
265
266 if (clk->prcc_kernel != -1)
267 writel(1 << clk->prcc_kernel, addr + PRCC_KCKEN);
268
269 if (clk->prcc_bus != -1)
270 writel(1 << clk->prcc_bus, addr + PRCC_PCKEN);
271}
272
273static void clk_prcc_disable(struct clk *clk)
274{
275 void __iomem *addr = __io_address(clkrst_base[clk->cluster]);
276
277 if (clk->prcc_bus != -1)
278 writel(1 << clk->prcc_bus, addr + PRCC_PCKDIS);
279
280 if (clk->prcc_kernel != -1)
281 writel(1 << clk->prcc_kernel, addr + PRCC_KCKDIS);
282}
283
284static struct clkops clk_prcc_ops = {
285 .enable = clk_prcc_enable,
286 .disable = clk_prcc_disable,
287};
288
289static struct clk clk_32khz = {
763eef8b 290 .name = "clk_32khz",
1df20afc
RV
291 .rate = 32000,
292};
293
294/*
295 * PRCMU level clock gating
296 */
297
298/* Bank 0 */
299static DEFINE_PRCMU_CLK(svaclk, 0x0, 2, SVAMMDSPCLK);
300static DEFINE_PRCMU_CLK(siaclk, 0x0, 3, SIAMMDSPCLK);
301static DEFINE_PRCMU_CLK(sgaclk, 0x0, 4, SGACLK);
302static DEFINE_PRCMU_CLK_RATE(uartclk, 0x0, 5, UARTCLK, 38400000);
303static DEFINE_PRCMU_CLK(msp02clk, 0x0, 6, MSP02CLK);
304static DEFINE_PRCMU_CLK(msp1clk, 0x0, 7, MSP1CLK); /* v1 */
305static DEFINE_PRCMU_CLK_RATE(i2cclk, 0x0, 8, I2CCLK, 48000000);
fbdc6d11 306static DEFINE_PRCMU_CLK_RATE(sdmmcclk, 0x0, 9, SDMMCCLK, 100000000);
1df20afc
RV
307static DEFINE_PRCMU_CLK(slimclk, 0x0, 10, SLIMCLK);
308static DEFINE_PRCMU_CLK(per1clk, 0x0, 11, PER1CLK);
309static DEFINE_PRCMU_CLK(per2clk, 0x0, 12, PER2CLK);
310static DEFINE_PRCMU_CLK(per3clk, 0x0, 13, PER3CLK);
311static DEFINE_PRCMU_CLK(per5clk, 0x0, 14, PER5CLK);
312static DEFINE_PRCMU_CLK_RATE(per6clk, 0x0, 15, PER6CLK, 133330000);
1df20afc
RV
313static DEFINE_PRCMU_CLK(lcdclk, 0x0, 17, LCDCLK);
314static DEFINE_PRCMU_CLK(bmlclk, 0x0, 18, BMLCLK);
315static DEFINE_PRCMU_CLK(hsitxclk, 0x0, 19, HSITXCLK);
316static DEFINE_PRCMU_CLK(hsirxclk, 0x0, 20, HSIRXCLK);
317static DEFINE_PRCMU_CLK(hdmiclk, 0x0, 21, HDMICLK);
318static DEFINE_PRCMU_CLK(apeatclk, 0x0, 22, APEATCLK);
319static DEFINE_PRCMU_CLK(apetraceclk, 0x0, 23, APETRACECLK);
320static DEFINE_PRCMU_CLK(mcdeclk, 0x0, 24, MCDECLK);
321static DEFINE_PRCMU_CLK(ipi2clk, 0x0, 25, IPI2CCLK);
322static DEFINE_PRCMU_CLK(dsialtclk, 0x0, 26, DSIALTCLK); /* v1 */
323static DEFINE_PRCMU_CLK(dmaclk, 0x0, 27, DMACLK);
324static DEFINE_PRCMU_CLK(b2r2clk, 0x0, 28, B2R2CLK);
325static DEFINE_PRCMU_CLK(tvclk, 0x0, 29, TVCLK);
326static DEFINE_PRCMU_CLK(uniproclk, 0x0, 30, UNIPROCLK); /* v1 */
327static DEFINE_PRCMU_CLK_RATE(sspclk, 0x0, 31, SSPCLK, 48000000); /* v1 */
328
329/* Bank 1 */
330static DEFINE_PRCMU_CLK(rngclk, 0x4, 0, RNGCLK); /* v1 */
331static DEFINE_PRCMU_CLK(uiccclk, 0x4, 1, UICCCLK); /* v1 */
332
333/*
334 * PRCC level clock gating
335 * Format: per#, clk, PCKEN bit, KCKEN bit, parent
336 */
337
338/* Peripheral Cluster #1 */
592b2f25 339static DEFINE_PRCC_CLK(1, i2c4, 10, 9, &clk_i2cclk);
1df20afc 340static DEFINE_PRCC_CLK(1, gpio0, 9, -1, NULL);
592b2f25 341static DEFINE_PRCC_CLK(1, slimbus0, 8, 8, &clk_slimclk);
c15def1c 342static DEFINE_PRCC_CLK(1, spi3, 7, -1, NULL);
592b2f25 343static DEFINE_PRCC_CLK(1, i2c2, 6, 6, &clk_i2cclk);
1df20afc 344static DEFINE_PRCC_CLK(1, sdi0, 5, 5, &clk_sdmmcclk);
c15def1c 345static DEFINE_PRCC_CLK(1, msp1, 4, 4, &clk_msp1clk);
592b2f25
SI
346static DEFINE_PRCC_CLK(1, msp0, 3, 3, &clk_msp02clk);
347static DEFINE_PRCC_CLK(1, i2c1, 2, 2, &clk_i2cclk);
348static DEFINE_PRCC_CLK(1, uart1, 1, 1, &clk_uartclk);
349static DEFINE_PRCC_CLK(1, uart0, 0, 0, &clk_uartclk);
1df20afc
RV
350
351/* Peripheral Cluster #2 */
c15def1c
LW
352static DEFINE_PRCC_CLK(2, gpio1, 11, -1, NULL);
353static DEFINE_PRCC_CLK(2, ssitx, 10, 7, NULL);
354static DEFINE_PRCC_CLK(2, ssirx, 9, 6, NULL);
355static DEFINE_PRCC_CLK(2, spi0, 8, -1, NULL);
356static DEFINE_PRCC_CLK(2, sdi3, 7, 5, &clk_sdmmcclk);
357static DEFINE_PRCC_CLK(2, sdi1, 6, 4, &clk_sdmmcclk);
358static DEFINE_PRCC_CLK(2, msp2, 5, 3, &clk_msp02clk);
359static DEFINE_PRCC_CLK(2, sdi4, 4, 2, &clk_sdmmcclk);
360static DEFINE_PRCC_CLK(2, pwl, 3, 1, NULL);
361static DEFINE_PRCC_CLK(2, spi1, 2, -1, NULL);
362static DEFINE_PRCC_CLK(2, spi2, 1, -1, NULL);
363static DEFINE_PRCC_CLK(2, i2c3, 0, 0, &clk_i2cclk);
1df20afc
RV
364
365/* Peripheral Cluster #3 */
592b2f25
SI
366static DEFINE_PRCC_CLK(3, gpio2, 8, -1, NULL);
367static DEFINE_PRCC_CLK(3, sdi5, 7, 7, &clk_sdmmcclk);
368static DEFINE_PRCC_CLK(3, uart2, 6, 6, &clk_uartclk);
369static DEFINE_PRCC_CLK(3, ske, 5, 5, &clk_32khz);
370static DEFINE_PRCC_CLK(3, sdi2, 4, 4, &clk_sdmmcclk);
371static DEFINE_PRCC_CLK(3, i2c0, 3, 3, &clk_i2cclk);
c15def1c
LW
372static DEFINE_PRCC_CLK(3, ssp1, 2, 2, &clk_sspclk);
373static DEFINE_PRCC_CLK(3, ssp0, 1, 1, &clk_sspclk);
592b2f25 374static DEFINE_PRCC_CLK(3, fsmc, 0, -1, NULL);
1df20afc
RV
375
376/* Peripheral Cluster #4 is in the always on domain */
377
378/* Peripheral Cluster #5 */
592b2f25 379static DEFINE_PRCC_CLK(5, gpio3, 1, -1, NULL);
c15def1c 380static DEFINE_PRCC_CLK(5, usb, 0, 0, NULL);
1df20afc
RV
381
382/* Peripheral Cluster #6 */
383
ba327b1e 384/* MTU ID in data */
585d188f
AW
385static DEFINE_PRCC_CLK_CUSTOM(6, mtu1, 9, -1, NULL, clk_mtu_get_rate, 1);
386static DEFINE_PRCC_CLK_CUSTOM(6, mtu0, 8, -1, NULL, clk_mtu_get_rate, 0);
387static DEFINE_PRCC_CLK(6, cfgreg, 7, 7, NULL);
388static DEFINE_PRCC_CLK(6, hash1, 6, -1, NULL);
389static DEFINE_PRCC_CLK(6, unipro, 5, 1, &clk_uniproclk);
390static DEFINE_PRCC_CLK(6, pka, 4, -1, NULL);
391static DEFINE_PRCC_CLK(6, hash0, 3, -1, NULL);
392static DEFINE_PRCC_CLK(6, cryp0, 2, -1, NULL);
393static DEFINE_PRCC_CLK(6, cryp1, 1, -1, NULL);
c15def1c 394static DEFINE_PRCC_CLK(6, rng, 0, 0, &clk_rngclk);
1df20afc 395
763eef8b
VG
396static struct clk clk_dummy_apb_pclk = {
397 .name = "apb_pclk",
398};
3126c7bc 399
c15def1c 400static struct clk_lookup u8500_clks[] = {
3126c7bc
RK
401 CLK(dummy_apb_pclk, NULL, "apb_pclk"),
402
1df20afc 403 /* Peripheral Cluster #1 */
af7dc228
RV
404 CLK(gpio0, "gpio.0", NULL),
405 CLK(gpio0, "gpio.1", NULL),
1df20afc
RV
406 CLK(slimbus0, "slimbus0", NULL),
407 CLK(i2c2, "nmk-i2c.2", NULL),
408 CLK(sdi0, "sdi0", NULL),
409 CLK(msp0, "msp0", NULL),
410 CLK(i2c1, "nmk-i2c.1", NULL),
411 CLK(uart1, "uart1", NULL),
412 CLK(uart0, "uart0", NULL),
413
414 /* Peripheral Cluster #3 */
af7dc228
RV
415 CLK(gpio2, "gpio.2", NULL),
416 CLK(gpio2, "gpio.3", NULL),
417 CLK(gpio2, "gpio.4", NULL),
418 CLK(gpio2, "gpio.5", NULL),
1df20afc
RV
419 CLK(sdi5, "sdi5", NULL),
420 CLK(uart2, "uart2", NULL),
421 CLK(ske, "ske", NULL),
4c61c845 422 CLK(ske, "nmk-ske-keypad", NULL),
1df20afc
RV
423 CLK(sdi2, "sdi2", NULL),
424 CLK(i2c0, "nmk-i2c.0", NULL),
425 CLK(fsmc, "fsmc", NULL),
426
427 /* Peripheral Cluster #5 */
af7dc228 428 CLK(gpio3, "gpio.8", NULL),
1df20afc
RV
429
430 /* Peripheral Cluster #6 */
431 CLK(hash1, "hash1", NULL),
432 CLK(pka, "pka", NULL),
433 CLK(hash0, "hash0", NULL),
434 CLK(cryp0, "cryp0", NULL),
585d188f 435 CLK(cryp1, "cryp1", NULL),
1df20afc
RV
436
437 /* PRCMU level clock gating */
438
439 /* Bank 0 */
440 CLK(svaclk, "sva", NULL),
441 CLK(siaclk, "sia", NULL),
442 CLK(sgaclk, "sga", NULL),
443 CLK(slimclk, "slim", NULL),
444 CLK(lcdclk, "lcd", NULL),
445 CLK(bmlclk, "bml", NULL),
446 CLK(hsitxclk, "stm-hsi.0", NULL),
447 CLK(hsirxclk, "stm-hsi.1", NULL),
448 CLK(hdmiclk, "hdmi", NULL),
449 CLK(apeatclk, "apeat", NULL),
450 CLK(apetraceclk, "apetrace", NULL),
451 CLK(mcdeclk, "mcde", NULL),
452 CLK(ipi2clk, "ipi2", NULL),
7b8ddb06 453 CLK(dmaclk, "dma40.0", NULL),
1df20afc
RV
454 CLK(b2r2clk, "b2r2", NULL),
455 CLK(tvclk, "tv", NULL),
1df20afc 456
1df20afc 457 /* Peripheral Cluster #1 */
592b2f25 458 CLK(i2c4, "nmk-i2c.4", NULL),
c15def1c
LW
459 CLK(spi3, "spi3", NULL),
460 CLK(msp1, "msp1", NULL),
1df20afc
RV
461
462 /* Peripheral Cluster #2 */
c15def1c
LW
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, "msp2", 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),
1df20afc
RV
476
477 /* Peripheral Cluster #3 */
c15def1c
LW
478 CLK(ssp1, "ssp1", NULL),
479 CLK(ssp0, "ssp0", NULL),
1df20afc
RV
480
481 /* Peripheral Cluster #5 */
c15def1c 482 CLK(usb, "musb-ux500.0", "usb"),
1df20afc
RV
483
484 /* Peripheral Cluster #6 */
c15def1c
LW
485 CLK(mtu1, "mtu1", NULL),
486 CLK(mtu0, "mtu0", NULL),
487 CLK(cfgreg, "cfgreg", NULL),
1df20afc 488 CLK(hash1, "hash1", NULL),
c15def1c
LW
489 CLK(unipro, "unipro", NULL),
490 CLK(rng, "rng", NULL),
1df20afc
RV
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),
c6b503ca
SK
501};
502
763eef8b
VG
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{
12520c43 556 struct dentry *d, *clk_d;
c066b65a 557 const char *p = c->name;
763eef8b 558
c066b65a
AV
559 if (!p)
560 p = "BUG";
763eef8b 561
c066b65a 562 clk_d = debugfs_create_dir(p, p_dentry);
763eef8b
VG
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:
12520c43 584 debugfs_remove_recursive(clk_d);
763eef8b
VG
585 return NULL;
586}
587
763eef8b
VG
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)) {
12520c43 604 debugfs_remove_recursive(c->dent);
763eef8b
VG
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
638static int __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
660late_initcall(clk_debugfs_init);
661#endif /* defined(CONFIG_DEBUG_FS) */
662
10958434 663unsigned long clk_smp_twd_rate = 500000000;
ef7a474c
LW
664
665unsigned long clk_smp_twd_get_rate(struct clk *clk)
666{
667 return clk_smp_twd_rate;
668}
669
670static struct clk clk_smp_twd = {
671 .get_rate = clk_smp_twd_get_rate,
672 .name = "smp_twd",
673};
674
675static struct clk_lookup clk_smp_twd_lookup = {
676 .dev_id = "smp_twd",
677 .clk = &clk_smp_twd,
678};
679
680#ifdef CONFIG_CPU_FREQ
681
682static int clk_twd_cpufreq_transition(struct notifier_block *nb,
683 unsigned long state, void *data)
684{
685 struct cpufreq_freqs *f = data;
686
687 if (state == CPUFREQ_PRECHANGE) {
688 /* Save frequency in simple Hz */
10958434 689 clk_smp_twd_rate = (f->new * 1000) / 2;
ef7a474c
LW
690 }
691
692 return NOTIFY_OK;
693}
694
695static struct notifier_block clk_twd_cpufreq_nb = {
696 .notifier_call = clk_twd_cpufreq_transition,
697};
698
699static int clk_init_smp_twd_cpufreq(void)
700{
701 return cpufreq_register_notifier(&clk_twd_cpufreq_nb,
702 CPUFREQ_TRANSITION_NOTIFIER);
703}
704late_initcall(clk_init_smp_twd_cpufreq);
705
706#endif
707
ba327b1e 708int __init clk_init(void)
c6b503ca 709{
c15def1c 710 if (cpu_is_u5500()) {
591d8dd7
RV
711 /* Clock tree for U5500 not implemented yet */
712 clk_prcc_ops.enable = clk_prcc_ops.disable = NULL;
713 clk_prcmu_ops.enable = clk_prcmu_ops.disable = NULL;
bab263e0
PF
714 clk_uartclk.rate = 36360000;
715 clk_sdmmcclk.rate = 99900000;
1df20afc
RV
716 }
717
c15def1c 718 clkdev_add_table(u8500_clks, ARRAY_SIZE(u8500_clks));
ef7a474c
LW
719 clkdev_add(&clk_smp_twd_lookup);
720
763eef8b 721#ifdef CONFIG_DEBUG_FS
c15def1c 722 clk_debugfs_add_table(u8500_clks, ARRAY_SIZE(u8500_clks));
763eef8b 723#endif
c6b503ca
SK
724 return 0;
725}