ARM: shmobile: r8a7790: add TPU PWM support
[deliverable/linux.git] / arch / arm / mach-shmobile / clock-sh73a0.c
CommitLineData
6d9598e2
MD
1/*
2 * sh73a0 clock framework support
3 *
4 * Copyright (C) 2010 Magnus Damm
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19#include <linux/init.h>
20#include <linux/kernel.h>
21#include <linux/io.h>
22#include <linux/sh_clk.h>
6ef9f6fd 23#include <linux/clkdev.h>
7653c318 24#include <asm/processor.h>
891cab3e 25#include <mach/clock.h>
6d9598e2 26#include <mach/common.h>
6d9598e2 27
0a4b04dc
AB
28#define FRQCRA IOMEM(0xe6150000)
29#define FRQCRB IOMEM(0xe6150004)
30#define FRQCRD IOMEM(0xe61500e4)
31#define VCLKCR1 IOMEM(0xe6150008)
32#define VCLKCR2 IOMEM(0xe615000C)
33#define VCLKCR3 IOMEM(0xe615001C)
34#define ZBCKCR IOMEM(0xe6150010)
35#define FLCKCR IOMEM(0xe6150014)
36#define SD0CKCR IOMEM(0xe6150074)
37#define SD1CKCR IOMEM(0xe6150078)
38#define SD2CKCR IOMEM(0xe615007C)
39#define FSIACKCR IOMEM(0xe6150018)
40#define FSIBCKCR IOMEM(0xe6150090)
41#define SUBCKCR IOMEM(0xe6150080)
42#define SPUACKCR IOMEM(0xe6150084)
43#define SPUVCKCR IOMEM(0xe6150094)
44#define MSUCKCR IOMEM(0xe6150088)
45#define HSICKCR IOMEM(0xe615008C)
46#define MFCK1CR IOMEM(0xe6150098)
47#define MFCK2CR IOMEM(0xe615009C)
48#define DSITCKCR IOMEM(0xe6150060)
49#define DSI0PCKCR IOMEM(0xe6150064)
50#define DSI1PCKCR IOMEM(0xe6150068)
f6d84f4a
MD
51#define DSI0PHYCR 0xe615006C
52#define DSI1PHYCR 0xe6150070
0a4b04dc
AB
53#define PLLECR IOMEM(0xe61500d0)
54#define PLL0CR IOMEM(0xe61500d8)
55#define PLL1CR IOMEM(0xe6150028)
56#define PLL2CR IOMEM(0xe615002c)
57#define PLL3CR IOMEM(0xe61500dc)
58#define SMSTPCR0 IOMEM(0xe6150130)
59#define SMSTPCR1 IOMEM(0xe6150134)
60#define SMSTPCR2 IOMEM(0xe6150138)
61#define SMSTPCR3 IOMEM(0xe615013c)
62#define SMSTPCR4 IOMEM(0xe6150140)
63#define SMSTPCR5 IOMEM(0xe6150144)
64#define CKSCR IOMEM(0xe61500c0)
6d9598e2
MD
65
66/* Fixed 32 KHz root clock from EXTALR pin */
67static struct clk r_clk = {
68 .rate = 32768,
69};
70
f6d84f4a
MD
71/*
72 * 26MHz default rate for the EXTAL1 root input clock.
73 * If needed, reset this with clk_set_rate() from the platform code.
74 */
75struct clk sh73a0_extal1_clk = {
76 .rate = 26000000,
77};
78
79/*
80 * 48MHz default rate for the EXTAL2 root input clock.
81 * If needed, reset this with clk_set_rate() from the platform code.
82 */
83struct clk sh73a0_extal2_clk = {
84 .rate = 48000000,
85};
86
7bcda508 87static struct sh_clk_ops main_clk_ops = {
f6d84f4a
MD
88 .recalc = followparent_recalc,
89};
90
91/* Main clock */
92static struct clk main_clk = {
891cab3e 93 /* .parent wll be set on sh73a0_clock_init() */
f6d84f4a
MD
94 .ops = &main_clk_ops,
95};
96
97/* PLL0, PLL1, PLL2, PLL3 */
98static unsigned long pll_recalc(struct clk *clk)
99{
100 unsigned long mult = 1;
101
71fc5099 102 if (__raw_readl(PLLECR) & (1 << clk->enable_bit)) {
f6d84f4a 103 mult = (((__raw_readl(clk->enable_reg) >> 24) & 0x3f) + 1);
71fc5099
MD
104 /* handle CFG bit for PLL1 and PLL2 */
105 switch (clk->enable_bit) {
106 case 1:
107 case 2:
108 if (__raw_readl(clk->enable_reg) & (1 << 20))
109 mult *= 2;
110 }
111 }
f6d84f4a
MD
112
113 return clk->parent->rate * mult;
114}
115
7bcda508 116static struct sh_clk_ops pll_clk_ops = {
f6d84f4a
MD
117 .recalc = pll_recalc,
118};
119
120static struct clk pll0_clk = {
121 .ops = &pll_clk_ops,
122 .flags = CLK_ENABLE_ON_INIT,
123 .parent = &main_clk,
124 .enable_reg = (void __iomem *)PLL0CR,
125 .enable_bit = 0,
6d9598e2
MD
126};
127
f6d84f4a
MD
128static struct clk pll1_clk = {
129 .ops = &pll_clk_ops,
130 .flags = CLK_ENABLE_ON_INIT,
131 .parent = &main_clk,
132 .enable_reg = (void __iomem *)PLL1CR,
133 .enable_bit = 1,
134};
135
136static struct clk pll2_clk = {
137 .ops = &pll_clk_ops,
138 .flags = CLK_ENABLE_ON_INIT,
139 .parent = &main_clk,
140 .enable_reg = (void __iomem *)PLL2CR,
141 .enable_bit = 2,
142};
143
144static struct clk pll3_clk = {
145 .ops = &pll_clk_ops,
146 .flags = CLK_ENABLE_ON_INIT,
147 .parent = &main_clk,
148 .enable_reg = (void __iomem *)PLL3CR,
149 .enable_bit = 3,
150};
151
891cab3e
KM
152/* A fixed divide block */
153SH_CLK_RATIO(div2, 1, 2);
154SH_CLK_RATIO(div7, 1, 7);
155SH_CLK_RATIO(div13, 1, 13);
d4775356 156
891cab3e
KM
157SH_FIXED_RATIO_CLK(extal1_div2_clk, sh73a0_extal1_clk, div2);
158SH_FIXED_RATIO_CLK(extal2_div2_clk, sh73a0_extal2_clk, div2);
159SH_FIXED_RATIO_CLK(main_div2_clk, main_clk, div2);
160SH_FIXED_RATIO_CLK(pll1_div2_clk, pll1_clk, div2);
161SH_FIXED_RATIO_CLK(pll1_div7_clk, pll1_clk, div7);
162SH_FIXED_RATIO_CLK(pll1_div13_clk, pll1_clk, div13);
d4775356
KM
163
164/* External input clock */
165struct clk sh73a0_extcki_clk = {
166};
167
168struct clk sh73a0_extalr_clk = {
169};
170
6d9598e2
MD
171static struct clk *main_clks[] = {
172 &r_clk,
f6d84f4a
MD
173 &sh73a0_extal1_clk,
174 &sh73a0_extal2_clk,
175 &extal1_div2_clk,
176 &extal2_div2_clk,
177 &main_clk,
d4775356 178 &main_div2_clk,
f6d84f4a
MD
179 &pll0_clk,
180 &pll1_clk,
181 &pll2_clk,
182 &pll3_clk,
183 &pll1_div2_clk,
d4775356
KM
184 &pll1_div7_clk,
185 &pll1_div13_clk,
186 &sh73a0_extcki_clk,
187 &sh73a0_extalr_clk,
f6d84f4a
MD
188};
189
7653c318 190static int frqcr_kick(void)
f6d84f4a 191{
7653c318
GL
192 int i;
193
194 /* set KICK bit in FRQCRB to update hardware setting, check success */
195 __raw_writel(__raw_readl(FRQCRB) | (1 << 31), FRQCRB);
196 for (i = 1000; i; i--)
197 if (__raw_readl(FRQCRB) & (1 << 31))
198 cpu_relax();
199 else
200 return i;
201
202 return -ETIMEDOUT;
203}
f6d84f4a 204
7653c318
GL
205static void div4_kick(struct clk *clk)
206{
207 frqcr_kick();
f6d84f4a
MD
208}
209
210static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
c070c203 211 24, 0, 36, 48, 7 };
f6d84f4a
MD
212
213static struct clk_div_mult_table div4_div_mult_table = {
214 .divisors = divisors,
215 .nr_divisors = ARRAY_SIZE(divisors),
216};
217
218static struct clk_div4_table div4_table = {
219 .div_mult_table = &div4_div_mult_table,
220 .kick = div4_kick,
221};
222
223enum { DIV4_I, DIV4_ZG, DIV4_M3, DIV4_B, DIV4_M1, DIV4_M2,
1f7ccd88 224 DIV4_Z, DIV4_ZX, DIV4_HP, DIV4_NR };
f6d84f4a
MD
225
226#define DIV4(_reg, _bit, _mask, _flags) \
227 SH_CLK_DIV4(&pll1_clk, _reg, _bit, _mask, _flags)
228
229static struct clk div4_clks[DIV4_NR] = {
bf519bfb 230 [DIV4_I] = DIV4(FRQCRA, 20, 0xdff, CLK_ENABLE_ON_INIT),
8a444474 231 [DIV4_ZG] = SH_CLK_DIV4(&pll0_clk, FRQCRA, 16, 0xd7f, CLK_ENABLE_ON_INIT),
bf519bfb
KM
232 [DIV4_M3] = DIV4(FRQCRA, 12, 0x1dff, CLK_ENABLE_ON_INIT),
233 [DIV4_B] = DIV4(FRQCRA, 8, 0xdff, CLK_ENABLE_ON_INIT),
234 [DIV4_M1] = DIV4(FRQCRA, 4, 0x1dff, 0),
235 [DIV4_M2] = DIV4(FRQCRA, 0, 0x1dff, 0),
8a444474 236 [DIV4_Z] = SH_CLK_DIV4(&pll0_clk, FRQCRB, 24, 0x97f, 0),
bf519bfb
KM
237 [DIV4_ZX] = DIV4(FRQCRB, 12, 0xdff, 0),
238 [DIV4_HP] = DIV4(FRQCRB, 4, 0xdff, 0),
f6d84f4a
MD
239};
240
fe7aa82d
GL
241static unsigned long twd_recalc(struct clk *clk)
242{
243 return clk_get_rate(clk->parent) / 4;
244}
245
246static struct sh_clk_ops twd_clk_ops = {
247 .recalc = twd_recalc,
248};
249
250static struct clk twd_clk = {
251 .parent = &div4_clks[DIV4_Z],
252 .ops = &twd_clk_ops,
253};
254
f6d84f4a
MD
255enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_ZB1,
256 DIV6_FLCTL, DIV6_SDHI0, DIV6_SDHI1, DIV6_SDHI2,
257 DIV6_FSIA, DIV6_FSIB, DIV6_SUB,
258 DIV6_SPUA, DIV6_SPUV, DIV6_MSU,
259 DIV6_HSI, DIV6_MFG1, DIV6_MFG2,
260 DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P,
261 DIV6_NR };
262
d4775356
KM
263static struct clk *vck_parent[8] = {
264 [0] = &pll1_div2_clk,
265 [1] = &pll2_clk,
266 [2] = &sh73a0_extcki_clk,
267 [3] = &sh73a0_extal2_clk,
268 [4] = &main_div2_clk,
269 [5] = &sh73a0_extalr_clk,
270 [6] = &main_clk,
271};
272
273static struct clk *pll_parent[4] = {
274 [0] = &pll1_div2_clk,
275 [1] = &pll2_clk,
276 [2] = &pll1_div13_clk,
277};
278
279static struct clk *hsi_parent[4] = {
280 [0] = &pll1_div2_clk,
281 [1] = &pll2_clk,
282 [2] = &pll1_div7_clk,
283};
284
285static struct clk *pll_extal2_parent[] = {
286 [0] = &pll1_div2_clk,
287 [1] = &pll2_clk,
288 [2] = &sh73a0_extal2_clk,
289 [3] = &sh73a0_extal2_clk,
290};
291
292static struct clk *dsi_parent[8] = {
293 [0] = &pll1_div2_clk,
294 [1] = &pll2_clk,
295 [2] = &main_clk,
296 [3] = &sh73a0_extal2_clk,
297 [4] = &sh73a0_extcki_clk,
298};
299
f6d84f4a 300static struct clk div6_clks[DIV6_NR] = {
d4775356
KM
301 [DIV6_VCK1] = SH_CLK_DIV6_EXT(VCLKCR1, 0,
302 vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
303 [DIV6_VCK2] = SH_CLK_DIV6_EXT(VCLKCR2, 0,
304 vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
305 [DIV6_VCK3] = SH_CLK_DIV6_EXT(VCLKCR3, 0,
306 vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
ca371d28 307 [DIV6_ZB1] = SH_CLK_DIV6_EXT(ZBCKCR, CLK_ENABLE_ON_INIT,
d4775356
KM
308 pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
309 [DIV6_FLCTL] = SH_CLK_DIV6_EXT(FLCKCR, 0,
310 pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
311 [DIV6_SDHI0] = SH_CLK_DIV6_EXT(SD0CKCR, 0,
312 pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
313 [DIV6_SDHI1] = SH_CLK_DIV6_EXT(SD1CKCR, 0,
314 pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
315 [DIV6_SDHI2] = SH_CLK_DIV6_EXT(SD2CKCR, 0,
316 pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
317 [DIV6_FSIA] = SH_CLK_DIV6_EXT(FSIACKCR, 0,
318 pll_parent, ARRAY_SIZE(pll_parent), 6, 1),
319 [DIV6_FSIB] = SH_CLK_DIV6_EXT(FSIBCKCR, 0,
320 pll_parent, ARRAY_SIZE(pll_parent), 6, 1),
321 [DIV6_SUB] = SH_CLK_DIV6_EXT(SUBCKCR, 0,
322 pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
323 [DIV6_SPUA] = SH_CLK_DIV6_EXT(SPUACKCR, 0,
324 pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
325 [DIV6_SPUV] = SH_CLK_DIV6_EXT(SPUVCKCR, 0,
326 pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
327 [DIV6_MSU] = SH_CLK_DIV6_EXT(MSUCKCR, 0,
328 pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
329 [DIV6_HSI] = SH_CLK_DIV6_EXT(HSICKCR, 0,
330 hsi_parent, ARRAY_SIZE(hsi_parent), 6, 2),
331 [DIV6_MFG1] = SH_CLK_DIV6_EXT(MFCK1CR, 0,
332 pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
333 [DIV6_MFG2] = SH_CLK_DIV6_EXT(MFCK2CR, 0,
334 pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
335 [DIV6_DSIT] = SH_CLK_DIV6_EXT(DSITCKCR, 0,
336 pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
337 [DIV6_DSI0P] = SH_CLK_DIV6_EXT(DSI0PCKCR, 0,
338 dsi_parent, ARRAY_SIZE(dsi_parent), 12, 3),
339 [DIV6_DSI1P] = SH_CLK_DIV6_EXT(DSI1PCKCR, 0,
340 dsi_parent, ARRAY_SIZE(dsi_parent), 12, 3),
6d9598e2
MD
341};
342
f5948bac
KM
343/* DSI DIV */
344static unsigned long dsiphy_recalc(struct clk *clk)
345{
346 u32 value;
347
348 value = __raw_readl(clk->mapping->base);
349
350 /* FIXME */
351 if (!(value & 0x000B8000))
352 return clk->parent->rate;
353
354 value &= 0x3f;
355 value += 1;
356
357 if ((value < 12) ||
358 (value > 33)) {
359 pr_err("DSIPHY has wrong value (%d)", value);
360 return 0;
361 }
362
363 return clk->parent->rate / value;
364}
365
366static long dsiphy_round_rate(struct clk *clk, unsigned long rate)
367{
368 return clk_rate_mult_range_round(clk, 12, 33, rate);
369}
370
371static void dsiphy_disable(struct clk *clk)
372{
373 u32 value;
374
375 value = __raw_readl(clk->mapping->base);
376 value &= ~0x000B8000;
377
378 __raw_writel(value , clk->mapping->base);
379}
380
381static int dsiphy_enable(struct clk *clk)
382{
383 u32 value;
384 int multi;
385
386 value = __raw_readl(clk->mapping->base);
387 multi = (value & 0x3f) + 1;
388
389 if ((multi < 12) || (multi > 33))
390 return -EIO;
391
392 __raw_writel(value | 0x000B8000, clk->mapping->base);
393
394 return 0;
395}
396
397static int dsiphy_set_rate(struct clk *clk, unsigned long rate)
398{
399 u32 value;
400 int idx;
401
402 idx = rate / clk->parent->rate;
403 if ((idx < 12) || (idx > 33))
404 return -EINVAL;
405
406 idx += -1;
407
408 value = __raw_readl(clk->mapping->base);
409 value = (value & ~0x3f) + idx;
410
411 __raw_writel(value, clk->mapping->base);
412
413 return 0;
414}
415
7bcda508 416static struct sh_clk_ops dsiphy_clk_ops = {
f5948bac
KM
417 .recalc = dsiphy_recalc,
418 .round_rate = dsiphy_round_rate,
419 .set_rate = dsiphy_set_rate,
420 .enable = dsiphy_enable,
421 .disable = dsiphy_disable,
422};
423
424static struct clk_mapping dsi0phy_clk_mapping = {
425 .phys = DSI0PHYCR,
426 .len = 4,
427};
428
429static struct clk_mapping dsi1phy_clk_mapping = {
430 .phys = DSI1PHYCR,
431 .len = 4,
432};
433
434static struct clk dsi0phy_clk = {
435 .ops = &dsiphy_clk_ops,
436 .parent = &div6_clks[DIV6_DSI0P], /* late install */
437 .mapping = &dsi0phy_clk_mapping,
438};
439
440static struct clk dsi1phy_clk = {
441 .ops = &dsiphy_clk_ops,
442 .parent = &div6_clks[DIV6_DSI1P], /* late install */
443 .mapping = &dsi1phy_clk_mapping,
444};
445
446static struct clk *late_main_clks[] = {
447 &dsi0phy_clk,
448 &dsi1phy_clk,
fe7aa82d 449 &twd_clk,
f5948bac
KM
450};
451
f6d84f4a 452enum { MSTP001,
ad054cbd 453 MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP100,
832290b2 454 MSTP219, MSTP218, MSTP217,
f6d84f4a 455 MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
12a7cfef 456 MSTP331, MSTP329, MSTP328, MSTP325, MSTP323, MSTP322,
681e1b3e 457 MSTP314, MSTP313, MSTP312, MSTP311,
33661c9e 458 MSTP303, MSTP302, MSTP301, MSTP300,
696d6e17 459 MSTP411, MSTP410, MSTP403,
6d9598e2
MD
460 MSTP_NR };
461
462#define MSTP(_parent, _reg, _bit, _flags) \
463 SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
464
465static struct clk mstp_clks[MSTP_NR] = {
f6d84f4a 466 [MSTP001] = MSTP(&div4_clks[DIV4_HP], SMSTPCR0, 1, 0), /* IIC2 */
ad054cbd
MD
467 [MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* CEU1 */
468 [MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* CSI2-RX1 */
469 [MSTP127] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 27, 0), /* CEU0 */
470 [MSTP126] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 26, 0), /* CSI2-RX0 */
5010f3db 471 [MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
170c7ab5 472 [MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX0 */
f6d84f4a 473 [MSTP116] = MSTP(&div4_clks[DIV4_HP], SMSTPCR1, 16, 0), /* IIC0 */
170c7ab5 474 [MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
f6d84f4a 475 [MSTP219] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 19, 0), /* SCIFA7 */
32103c7b 476 [MSTP218] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* SY-DMAC */
832290b2 477 [MSTP217] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 17, 0), /* MP-DMAC */
f6d84f4a
MD
478 [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
479 [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
480 [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
481 [MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */
482 [MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */
483 [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
484 [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
485 [MSTP331] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 31, 0), /* SCIFA6 */
6d9598e2 486 [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
ea7e1a5a 487 [MSTP328] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 28, 0), /*FSI*/
5a1b70a4 488 [MSTP325] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 25, 0), /* IrDA */
f6d84f4a 489 [MSTP323] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 23, 0), /* IIC1 */
12a7cfef 490 [MSTP322] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 22, 0), /* USB */
fb66c523
MD
491 [MSTP314] = MSTP(&div6_clks[DIV6_SDHI0], SMSTPCR3, 14, 0), /* SDHI0 */
492 [MSTP313] = MSTP(&div6_clks[DIV6_SDHI1], SMSTPCR3, 13, 0), /* SDHI1 */
6bf45a10 493 [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMCIF0 */
fb66c523 494 [MSTP311] = MSTP(&div6_clks[DIV6_SDHI2], SMSTPCR3, 11, 0), /* SDHI2 */
33661c9e
MD
495 [MSTP303] = MSTP(&main_div2_clk, SMSTPCR3, 3, 0), /* TPU1 */
496 [MSTP302] = MSTP(&main_div2_clk, SMSTPCR3, 2, 0), /* TPU2 */
497 [MSTP301] = MSTP(&main_div2_clk, SMSTPCR3, 1, 0), /* TPU3 */
498 [MSTP300] = MSTP(&main_div2_clk, SMSTPCR3, 0, 0), /* TPU4 */
f6d84f4a
MD
499 [MSTP411] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 11, 0), /* IIC3 */
500 [MSTP410] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 10, 0), /* IIC4 */
019c4ae3 501 [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
6d9598e2
MD
502};
503
48609533
SH
504/* The lookups structure below includes duplicate entries for some clocks
505 * with alternate names.
506 * - The traditional name used when a device is initialised with platform data
507 * - The name used when a device is initialised using device tree
508 * The longer-term aim is to remove these duplicates, and indeed the
509 * lookups table entirely, by describing clocks using device tree.
510 */
6d9598e2 511static struct clk_lookup lookups[] = {
f6d84f4a
MD
512 /* main clocks */
513 CLKDEV_CON_ID("r_clk", &r_clk),
fe7aa82d 514 CLKDEV_DEV_ID("smp_twd", &twd_clk), /* smp_twd */
f6d84f4a 515
170c7ab5 516 /* DIV6 clocks */
ad054cbd
MD
517 CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
518 CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
519 CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
fb66c523
MD
520 CLKDEV_CON_ID("sdhi0_clk", &div6_clks[DIV6_SDHI0]),
521 CLKDEV_CON_ID("sdhi1_clk", &div6_clks[DIV6_SDHI1]),
522 CLKDEV_CON_ID("sdhi2_clk", &div6_clks[DIV6_SDHI2]),
170c7ab5
MD
523 CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
524 CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
9250741e
KM
525 CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
526 CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
f5948bac
KM
527 CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.0", &dsi0phy_clk),
528 CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.1", &dsi1phy_clk),
170c7ab5 529
6d9598e2 530 /* MSTP32 clocks */
696d6e17 531 CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */
48609533 532 CLKDEV_DEV_ID("e6824000.i2c", &mstp_clks[MSTP001]), /* I2C2 */
ad054cbd
MD
533 CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[MSTP129]), /* CEU1 */
534 CLKDEV_DEV_ID("sh-mobile-csi2.1", &mstp_clks[MSTP128]), /* CSI2-RX1 */
535 CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU0 */
536 CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2-RX0 */
5010f3db
MD
537 CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), /* TMU00 */
538 CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */
170c7ab5 539 CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */
ad054cbd 540 CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* I2C0 */
48609533 541 CLKDEV_DEV_ID("e6820000.i2c", &mstp_clks[MSTP116]), /* I2C0 */
ad054cbd 542 CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
6d9598e2 543 CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP219]), /* SCIFA7 */
32103c7b 544 CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* SY-DMAC */
832290b2 545 CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]), /* MP-DMAC */
6d9598e2
MD
546 CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
547 CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]), /* SCIFB */
548 CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
549 CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
550 CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
551 CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
552 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
553 CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */
554 CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
ea7e1a5a 555 CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI */
a33bb8a2 556 CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */
b028f94b 557 CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */
48609533 558 CLKDEV_DEV_ID("e6822000.i2c", &mstp_clks[MSTP323]), /* I2C1 */
12a7cfef 559 CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP322]), /* USB */
fb66c523 560 CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
df2ddd7b 561 CLKDEV_DEV_ID("ee100000.sdhi", &mstp_clks[MSTP314]), /* SDHI0 */
fb66c523 562 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
df2ddd7b 563 CLKDEV_DEV_ID("ee120000.sdhi", &mstp_clks[MSTP313]), /* SDHI1 */
6bf45a10 564 CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */
93301f5d 565 CLKDEV_DEV_ID("e6bd0000.mmcif", &mstp_clks[MSTP312]), /* MMCIF0 */
fb66c523 566 CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), /* SDHI2 */
df2ddd7b 567 CLKDEV_DEV_ID("ee140000.sdhi", &mstp_clks[MSTP311]), /* SDHI2 */
33661c9e
MD
568 CLKDEV_DEV_ID("leds-renesas-tpu.12", &mstp_clks[MSTP303]), /* TPU1 */
569 CLKDEV_DEV_ID("leds-renesas-tpu.21", &mstp_clks[MSTP302]), /* TPU2 */
570 CLKDEV_DEV_ID("leds-renesas-tpu.30", &mstp_clks[MSTP301]), /* TPU3 */
571 CLKDEV_DEV_ID("leds-renesas-tpu.41", &mstp_clks[MSTP300]), /* TPU4 */
b028f94b 572 CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* I2C3 */
48609533 573 CLKDEV_DEV_ID("e6826000.i2c", &mstp_clks[MSTP411]), /* I2C3 */
b028f94b 574 CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */
48609533 575 CLKDEV_DEV_ID("e6828000.i2c", &mstp_clks[MSTP410]), /* I2C4 */
019c4ae3 576 CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
6d9598e2
MD
577};
578
579void __init sh73a0_clock_init(void)
580{
581 int k, ret = 0;
582
fb66c523
MD
583 /* Set SDHI clocks to a known state */
584 __raw_writel(0x108, SD0CKCR);
585 __raw_writel(0x108, SD1CKCR);
586 __raw_writel(0x108, SD2CKCR);
587
f6d84f4a 588 /* detect main clock parent */
86d84083 589 switch ((__raw_readl(CKSCR) >> 28) & 0x03) {
f6d84f4a
MD
590 case 0:
591 main_clk.parent = &sh73a0_extal1_clk;
592 break;
593 case 1:
594 main_clk.parent = &extal1_div2_clk;
595 break;
596 case 2:
597 main_clk.parent = &sh73a0_extal2_clk;
598 break;
599 case 3:
600 main_clk.parent = &extal2_div2_clk;
601 break;
602 }
603
6d9598e2
MD
604 for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
605 ret = clk_register(main_clks[k]);
606
f6d84f4a
MD
607 if (!ret)
608 ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
609
610 if (!ret)
d4775356 611 ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR);
f6d84f4a 612
6d9598e2 613 if (!ret)
64e9de2f 614 ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
6d9598e2 615
f5948bac
KM
616 for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
617 ret = clk_register(late_main_clks[k]);
618
6d9598e2
MD
619 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
620
621 if (!ret)
6b6a4c06 622 shmobile_clk_init();
6d9598e2
MD
623 else
624 panic("failed to setup sh73a0 clocks\n");
625}
This page took 0.162722 seconds and 5 git commands to generate.