Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
clock-sh7372.c
Go to the documentation of this file.
1 /*
2  * SH7372 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>
23 #include <linux/clkdev.h>
24 #include <mach/common.h>
25 
26 /* SH7372 registers */
27 #define FRQCRA IOMEM(0xe6150000)
28 #define FRQCRB IOMEM(0xe6150004)
29 #define FRQCRC IOMEM(0xe61500e0)
30 #define FRQCRD IOMEM(0xe61500e4)
31 #define VCLKCR1 IOMEM(0xe6150008)
32 #define VCLKCR2 IOMEM(0xe615000c)
33 #define VCLKCR3 IOMEM(0xe615001c)
34 #define FMSICKCR IOMEM(0xe6150010)
35 #define FMSOCKCR IOMEM(0xe6150014)
36 #define FSIACKCR IOMEM(0xe6150018)
37 #define FSIBCKCR IOMEM(0xe6150090)
38 #define SUBCKCR IOMEM(0xe6150080)
39 #define SPUCKCR IOMEM(0xe6150084)
40 #define VOUCKCR IOMEM(0xe6150088)
41 #define HDMICKCR IOMEM(0xe6150094)
42 #define DSITCKCR IOMEM(0xe6150060)
43 #define DSI0PCKCR IOMEM(0xe6150064)
44 #define DSI1PCKCR IOMEM(0xe6150098)
45 #define PLLC01CR IOMEM(0xe6150028)
46 #define PLLC2CR IOMEM(0xe615002c)
47 #define RMSTPCR0 IOMEM(0xe6150110)
48 #define RMSTPCR1 IOMEM(0xe6150114)
49 #define RMSTPCR2 IOMEM(0xe6150118)
50 #define RMSTPCR3 IOMEM(0xe615011c)
51 #define RMSTPCR4 IOMEM(0xe6150120)
52 #define SMSTPCR0 IOMEM(0xe6150130)
53 #define SMSTPCR1 IOMEM(0xe6150134)
54 #define SMSTPCR2 IOMEM(0xe6150138)
55 #define SMSTPCR3 IOMEM(0xe615013c)
56 #define SMSTPCR4 IOMEM(0xe6150140)
57 
58 #define FSIDIVA 0xFE1F8000
59 #define FSIDIVB 0xFE1F8008
60 
61 /* Platforms must set frequency on their DV_CLKI pin */
63 };
64 
65 /* Fixed 32 KHz root clock from EXTALR pin */
66 static struct clk r_clk = {
67  .rate = 32768,
68 };
69 
70 /*
71  * 26MHz default rate for the EXTAL1 root input clock.
72  * If needed, reset this with clk_set_rate() from the platform code.
73  */
75  .rate = 26000000,
76 };
77 
78 /*
79  * 48MHz default rate for the EXTAL2 root input clock.
80  * If needed, reset this with clk_set_rate() from the platform code.
81  */
83  .rate = 48000000,
84 };
85 
86 /* A fixed divide-by-2 block */
87 static unsigned long div2_recalc(struct clk *clk)
88 {
89  return clk->parent->rate / 2;
90 }
91 
92 static struct sh_clk_ops div2_clk_ops = {
93  .recalc = div2_recalc,
94 };
95 
96 /* Divide dv_clki by two */
98  .ops = &div2_clk_ops,
99  .parent = &sh7372_dv_clki_clk,
100 };
101 
102 /* Divide extal1 by two */
103 static struct clk extal1_div2_clk = {
104  .ops = &div2_clk_ops,
105  .parent = &sh7372_extal1_clk,
106 };
107 
108 /* Divide extal2 by two */
109 static struct clk extal2_div2_clk = {
110  .ops = &div2_clk_ops,
111  .parent = &sh7372_extal2_clk,
112 };
113 
114 /* Divide extal2 by four */
115 static struct clk extal2_div4_clk = {
116  .ops = &div2_clk_ops,
117  .parent = &extal2_div2_clk,
118 };
119 
120 /* PLLC0 and PLLC1 */
121 static unsigned long pllc01_recalc(struct clk *clk)
122 {
123  unsigned long mult = 1;
124 
125  if (__raw_readl(PLLC01CR) & (1 << 14))
126  mult = (((__raw_readl(clk->enable_reg) >> 24) & 0x3f) + 1) * 2;
127 
128  return clk->parent->rate * mult;
129 }
130 
131 static struct sh_clk_ops pllc01_clk_ops = {
132  .recalc = pllc01_recalc,
133 };
134 
135 static struct clk pllc0_clk = {
136  .ops = &pllc01_clk_ops,
137  .flags = CLK_ENABLE_ON_INIT,
138  .parent = &extal1_div2_clk,
139  .enable_reg = (void __iomem *)FRQCRC,
140 };
141 
142 static struct clk pllc1_clk = {
143  .ops = &pllc01_clk_ops,
144  .flags = CLK_ENABLE_ON_INIT,
145  .parent = &extal1_div2_clk,
146  .enable_reg = (void __iomem *)FRQCRA,
147 };
148 
149 /* Divide PLLC1 by two */
150 static struct clk pllc1_div2_clk = {
151  .ops = &div2_clk_ops,
152  .parent = &pllc1_clk,
153 };
154 
155 /* PLLC2 */
156 
157 /* Indices are important - they are the actual src selecting values */
158 static struct clk *pllc2_parent[] = {
159  [0] = &extal1_div2_clk,
160  [1] = &extal2_div2_clk,
162 };
163 
164 /* Only multipliers 20 * 2 to 46 * 2 are valid, last entry for CPUFREQ_TABLE_END */
165 static struct cpufreq_frequency_table pllc2_freq_table[29];
166 
167 static void pllc2_table_rebuild(struct clk *clk)
168 {
169  int i;
170 
171  /* Initialise PLLC2 frequency table */
172  for (i = 0; i < ARRAY_SIZE(pllc2_freq_table) - 2; i++) {
173  pllc2_freq_table[i].frequency = clk->parent->rate * (i + 20) * 2;
174  pllc2_freq_table[i].index = i;
175  }
176 
177  /* This is a special entry - switching PLL off makes it a repeater */
178  pllc2_freq_table[i].frequency = clk->parent->rate;
179  pllc2_freq_table[i].index = i;
180 
181  pllc2_freq_table[++i].frequency = CPUFREQ_TABLE_END;
182  pllc2_freq_table[i].index = i;
183 }
184 
185 static unsigned long pllc2_recalc(struct clk *clk)
186 {
187  unsigned long mult = 1;
188 
189  pllc2_table_rebuild(clk);
190 
191  /*
192  * If the PLL is off, mult == 1, clk->rate will be updated in
193  * pllc2_enable().
194  */
195  if (__raw_readl(PLLC2CR) & (1 << 31))
196  mult = (((__raw_readl(PLLC2CR) >> 24) & 0x3f) + 1) * 2;
197 
198  return clk->parent->rate * mult;
199 }
200 
201 static long pllc2_round_rate(struct clk *clk, unsigned long rate)
202 {
203  return clk_rate_table_round(clk, clk->freq_table, rate);
204 }
205 
206 static int pllc2_enable(struct clk *clk)
207 {
208  int i;
209 
210  __raw_writel(__raw_readl(PLLC2CR) | 0x80000000, PLLC2CR);
211 
212  for (i = 0; i < 100; i++)
213  if (__raw_readl(PLLC2CR) & 0x80000000) {
214  clk->rate = pllc2_recalc(clk);
215  return 0;
216  }
217 
218  pr_err("%s(): timeout!\n", __func__);
219 
220  return -ETIMEDOUT;
221 }
222 
223 static void pllc2_disable(struct clk *clk)
224 {
225  __raw_writel(__raw_readl(PLLC2CR) & ~0x80000000, PLLC2CR);
226 }
227 
228 static int pllc2_set_rate(struct clk *clk, unsigned long rate)
229 {
230  unsigned long value;
231  int idx;
232 
233  idx = clk_rate_table_find(clk, clk->freq_table, rate);
234  if (idx < 0)
235  return idx;
236 
237  if (rate == clk->parent->rate)
238  return -EINVAL;
239 
240  value = __raw_readl(PLLC2CR) & ~(0x3f << 24);
241 
242  __raw_writel(value | ((idx + 19) << 24), PLLC2CR);
243 
244  clk->rate = clk->freq_table[idx].frequency;
245 
246  return 0;
247 }
248 
249 static int pllc2_set_parent(struct clk *clk, struct clk *parent)
250 {
251  u32 value;
252  int ret, i;
253 
254  if (!clk->parent_table || !clk->parent_num)
255  return -EINVAL;
256 
257  /* Search the parent */
258  for (i = 0; i < clk->parent_num; i++)
259  if (clk->parent_table[i] == parent)
260  break;
261 
262  if (i == clk->parent_num)
263  return -ENODEV;
264 
265  ret = clk_reparent(clk, parent);
266  if (ret < 0)
267  return ret;
268 
269  value = __raw_readl(PLLC2CR) & ~(3 << 6);
270 
271  __raw_writel(value | (i << 6), PLLC2CR);
272 
273  /* Rebiuld the frequency table */
274  pllc2_table_rebuild(clk);
275 
276  return 0;
277 }
278 
279 static struct sh_clk_ops pllc2_clk_ops = {
280  .recalc = pllc2_recalc,
281  .round_rate = pllc2_round_rate,
282  .set_rate = pllc2_set_rate,
283  .enable = pllc2_enable,
284  .disable = pllc2_disable,
285  .set_parent = pllc2_set_parent,
286 };
287 
288 struct clk sh7372_pllc2_clk = {
289  .ops = &pllc2_clk_ops,
290  .parent = &extal1_div2_clk,
291  .freq_table = pllc2_freq_table,
292  .nr_freqs = ARRAY_SIZE(pllc2_freq_table) - 1,
293  .parent_table = pllc2_parent,
294  .parent_num = ARRAY_SIZE(pllc2_parent),
295 };
296 
297 /* External input clock (pin name: FSIACK/FSIBCK ) */
298 struct clk sh7372_fsiack_clk = {
299 };
300 
301 struct clk sh7372_fsibck_clk = {
302 };
303 
304 static struct clk *main_clks[] = {
306  &r_clk,
310  &extal1_div2_clk,
311  &extal2_div2_clk,
312  &extal2_div4_clk,
313  &pllc0_clk,
314  &pllc1_clk,
315  &pllc1_div2_clk,
319 };
320 
321 static void div4_kick(struct clk *clk)
322 {
323  unsigned long value;
324 
325  /* set KICK bit in FRQCRB to update hardware setting */
326  value = __raw_readl(FRQCRB);
327  value |= (1 << 31);
328  __raw_writel(value, FRQCRB);
329 }
330 
331 static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
332  24, 32, 36, 48, 0, 72, 96, 0 };
333 
334 static struct clk_div_mult_table div4_div_mult_table = {
335  .divisors = divisors,
336  .nr_divisors = ARRAY_SIZE(divisors),
337 };
338 
339 static struct clk_div4_table div4_table = {
340  .div_mult_table = &div4_div_mult_table,
341  .kick = div4_kick,
342 };
343 
348 
349 #define DIV4(_reg, _bit, _mask, _flags) \
350  SH_CLK_DIV4(&pllc1_clk, _reg, _bit, _mask, _flags)
351 
352 static struct clk div4_clks[DIV4_NR] = {
353  [DIV4_I] = DIV4(FRQCRA, 20, 0x6fff, CLK_ENABLE_ON_INIT),
354  [DIV4_ZG] = DIV4(FRQCRA, 16, 0x6fff, CLK_ENABLE_ON_INIT),
355  [DIV4_B] = DIV4(FRQCRA, 8, 0x6fff, CLK_ENABLE_ON_INIT),
356  [DIV4_M1] = DIV4(FRQCRA, 4, 0x6fff, CLK_ENABLE_ON_INIT),
357  [DIV4_CSIR] = DIV4(FRQCRA, 0, 0x6fff, 0),
358  [DIV4_ZTR] = DIV4(FRQCRB, 20, 0x6fff, 0),
359  [DIV4_ZT] = DIV4(FRQCRB, 16, 0x6fff, 0),
360  [DIV4_ZX] = DIV4(FRQCRB, 12, 0x6fff, 0),
361  [DIV4_HP] = DIV4(FRQCRB, 4, 0x6fff, 0),
362  [DIV4_ISPB] = DIV4(FRQCRC, 20, 0x6fff, 0),
363  [DIV4_S] = DIV4(FRQCRC, 12, 0x6fff, 0),
364  [DIV4_ZB] = DIV4(FRQCRC, 8, 0x6fff, 0),
365  [DIV4_ZB3] = DIV4(FRQCRC, 4, 0x6fff, 0),
366  [DIV4_CP] = DIV4(FRQCRC, 0, 0x6fff, 0),
367  [DIV4_DDRP] = DIV4(FRQCRD, 0, 0x677c, 0),
368 };
369 
374 
375 static struct clk div6_clks[DIV6_NR] = {
376  [DIV6_VCK1] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR1, 0),
377  [DIV6_VCK2] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR2, 0),
378  [DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0),
379  [DIV6_FMSI] = SH_CLK_DIV6(&pllc1_div2_clk, FMSICKCR, 0),
380  [DIV6_FMSO] = SH_CLK_DIV6(&pllc1_div2_clk, FMSOCKCR, 0),
381  [DIV6_SUB] = SH_CLK_DIV6(&sh7372_extal2_clk, SUBCKCR, 0),
382  [DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0),
383  [DIV6_VOU] = SH_CLK_DIV6(&pllc1_div2_clk, VOUCKCR, 0),
384  [DIV6_DSIT] = SH_CLK_DIV6(&pllc1_div2_clk, DSITCKCR, 0),
385  [DIV6_DSI0P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI0PCKCR, 0),
386  [DIV6_DSI1P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI1PCKCR, 0),
387 };
388 
390 
391 /* Indices are important - they are the actual src selecting values */
392 static struct clk *hdmi_parent[] = {
393  [0] = &pllc1_div2_clk,
394  [1] = &sh7372_pllc2_clk,
395  [2] = &sh7372_dv_clki_clk,
396  [3] = NULL, /* pllc2_div4 not implemented yet */
397 };
398 
399 static struct clk *fsiackcr_parent[] = {
400  [0] = &pllc1_div2_clk,
401  [1] = &sh7372_pllc2_clk,
402  [2] = &sh7372_fsiack_clk, /* external input for FSI A */
403  [3] = NULL, /* setting prohibited */
404 };
405 
406 static struct clk *fsibckcr_parent[] = {
407  [0] = &pllc1_div2_clk,
408  [1] = &sh7372_pllc2_clk,
409  [2] = &sh7372_fsibck_clk, /* external input for FSI B */
410  [3] = NULL, /* setting prohibited */
411 };
412 
413 static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = {
415  hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2),
417  fsiackcr_parent, ARRAY_SIZE(fsiackcr_parent), 6, 2),
419  fsibckcr_parent, ARRAY_SIZE(fsibckcr_parent), 6, 2),
420 };
421 
422 /* FSI DIV */
423 static unsigned long fsidiv_recalc(struct clk *clk)
424 {
425  unsigned long value;
426 
427  value = __raw_readl(clk->mapping->base);
428 
429  value >>= 16;
430  if (value < 2)
431  return 0;
432 
433  return clk->parent->rate / value;
434 }
435 
436 static long fsidiv_round_rate(struct clk *clk, unsigned long rate)
437 {
438  return clk_rate_div_range_round(clk, 2, 0xffff, rate);
439 }
440 
441 static void fsidiv_disable(struct clk *clk)
442 {
443  __raw_writel(0, clk->mapping->base);
444 }
445 
446 static int fsidiv_enable(struct clk *clk)
447 {
448  unsigned long value;
449 
450  value = __raw_readl(clk->mapping->base) >> 16;
451  if (value < 2)
452  return -EIO;
453 
454  __raw_writel((value << 16) | 0x3, clk->mapping->base);
455 
456  return 0;
457 }
458 
459 static int fsidiv_set_rate(struct clk *clk, unsigned long rate)
460 {
461  int idx;
462 
463  idx = (clk->parent->rate / rate) & 0xffff;
464  if (idx < 2)
465  return -EINVAL;
466 
467  __raw_writel(idx << 16, clk->mapping->base);
468  return 0;
469 }
470 
471 static struct sh_clk_ops fsidiv_clk_ops = {
472  .recalc = fsidiv_recalc,
473  .round_rate = fsidiv_round_rate,
474  .set_rate = fsidiv_set_rate,
475  .enable = fsidiv_enable,
476  .disable = fsidiv_disable,
477 };
478 
479 static struct clk_mapping fsidiva_clk_mapping = {
480  .phys = FSIDIVA,
481  .len = 8,
482 };
483 
484 struct clk sh7372_fsidiva_clk = {
485  .ops = &fsidiv_clk_ops,
486  .parent = &div6_reparent_clks[DIV6_FSIA], /* late install */
487  .mapping = &fsidiva_clk_mapping,
488 };
489 
490 static struct clk_mapping fsidivb_clk_mapping = {
491  .phys = FSIDIVB,
492  .len = 8,
493 };
494 
495 struct clk sh7372_fsidivb_clk = {
496  .ops = &fsidiv_clk_ops,
497  .parent = &div6_reparent_clks[DIV6_FSIB], /* late install */
498  .mapping = &fsidivb_clk_mapping,
499 };
500 
501 static struct clk *late_main_clks[] = {
504 };
505 
506 enum { MSTP001, MSTP000,
518 
519 #define MSTP(_parent, _reg, _bit, _flags) \
520  SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
521 
522 static struct clk mstp_clks[MSTP_NR] = {
523  [MSTP001] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR0, 1, 0), /* IIC2 */
524  [MSTP000] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR0, 0, 0), /* MSIOF0 */
525  [MSTP131] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 31, 0), /* VEU3 */
526  [MSTP130] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 30, 0), /* VEU2 */
527  [MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* VEU1 */
528  [MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* VEU0 */
529  [MSTP127] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 27, 0), /* CEU */
530  [MSTP126] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 26, 0), /* CSI2 */
531  [MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
532  [MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX */
533  [MSTP117] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */
534  [MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */
535  [MSTP113] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 13, 0), /* MERAM */
536  [MSTP106] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 6, 0), /* JPU */
537  [MSTP101] = MSTP(&div4_clks[DIV4_M1], SMSTPCR1, 1, 0), /* VPU */
538  [MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
539  [MSTP223] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR2, 23, 0), /* SPU2 */
540  [MSTP218] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* DMAC1 */
541  [MSTP217] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 17, 0), /* DMAC2 */
542  [MSTP216] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 16, 0), /* DMAC3 */
543  [MSTP214] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 14, 0), /* USBDMAC */
544  [MSTP208] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 8, 0), /* MSIOF1 */
545  [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
546  [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
547  [MSTP205] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 5, 0), /* MSIOF2 */
548  [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
549  [MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */
550  [MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */
551  [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
552  [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
553  [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSI2 */
554  [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
555  [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */
556  [MSTP315] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 15, 0), /* FLCTL*/
557  [MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */
558  [MSTP313] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */
559  [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMC */
560  [MSTP423] = MSTP(&div4_clks[DIV4_B], SMSTPCR4, 23, 0), /* DSITX1 */
561  [MSTP415] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 15, 0), /* SDHI2 */
562  [MSTP413] = MSTP(&pllc1_div2_clk, SMSTPCR4, 13, 0), /* HDMI */
563  [MSTP411] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 11, 0), /* IIC3 */
564  [MSTP410] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 10, 0), /* IIC4 */
565  [MSTP407] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 7, 0), /* USB-DMAC1 */
566  [MSTP406] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 6, 0), /* USB1 */
567  [MSTP405] = MSTP(&r_clk, SMSTPCR4, 5, 0), /* CMT4 */
568  [MSTP404] = MSTP(&r_clk, SMSTPCR4, 4, 0), /* CMT3 */
569  [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
570  [MSTP400] = MSTP(&r_clk, SMSTPCR4, 0, 0), /* CMT2 */
571 };
572 
573 static struct clk_lookup lookups[] = {
574  /* main clocks */
575  CLKDEV_CON_ID("dv_clki_div2_clk", &sh7372_dv_clki_div2_clk),
576  CLKDEV_CON_ID("r_clk", &r_clk),
577  CLKDEV_CON_ID("extal1", &sh7372_extal1_clk),
578  CLKDEV_CON_ID("extal2", &sh7372_extal2_clk),
579  CLKDEV_CON_ID("extal1_div2_clk", &extal1_div2_clk),
580  CLKDEV_CON_ID("extal2_div2_clk", &extal2_div2_clk),
581  CLKDEV_CON_ID("extal2_div4_clk", &extal2_div4_clk),
582  CLKDEV_CON_ID("pllc0_clk", &pllc0_clk),
583  CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
584  CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
585  CLKDEV_CON_ID("pllc2_clk", &sh7372_pllc2_clk),
586 
587  /* DIV4 clocks */
588  CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
589  CLKDEV_CON_ID("zg_clk", &div4_clks[DIV4_ZG]),
590  CLKDEV_CON_ID("b_clk", &div4_clks[DIV4_B]),
591  CLKDEV_CON_ID("m1_clk", &div4_clks[DIV4_M1]),
592  CLKDEV_CON_ID("csir_clk", &div4_clks[DIV4_CSIR]),
593  CLKDEV_CON_ID("ztr_clk", &div4_clks[DIV4_ZTR]),
594  CLKDEV_CON_ID("zt_clk", &div4_clks[DIV4_ZT]),
595  CLKDEV_CON_ID("zx_clk", &div4_clks[DIV4_ZX]),
596  CLKDEV_CON_ID("hp_clk", &div4_clks[DIV4_HP]),
597  CLKDEV_CON_ID("ispb_clk", &div4_clks[DIV4_ISPB]),
598  CLKDEV_CON_ID("s_clk", &div4_clks[DIV4_S]),
599  CLKDEV_CON_ID("zb_clk", &div4_clks[DIV4_ZB]),
600  CLKDEV_CON_ID("zb3_clk", &div4_clks[DIV4_ZB3]),
601  CLKDEV_CON_ID("cp_clk", &div4_clks[DIV4_CP]),
602  CLKDEV_CON_ID("ddrp_clk", &div4_clks[DIV4_DDRP]),
603 
604  /* DIV6 clocks */
605  CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
606  CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
607  CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
608  CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]),
609  CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]),
610  CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]),
611  CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]),
612  CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]),
613  CLKDEV_CON_ID("hdmi_clk", &div6_reparent_clks[DIV6_HDMI]),
614  CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
615  CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
616  CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
617  CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
618 
619  /* MSTP32 clocks */
620  CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */
621  CLKDEV_DEV_ID("spi_sh_msiof.0", &mstp_clks[MSTP000]), /* MSIOF0 */
622  CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[MSTP131]), /* VEU3 */
623  CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */
624  CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[MSTP129]), /* VEU1 */
625  CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[MSTP128]), /* VEU0 */
626  CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU */
627  CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2 */
628  CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), /* TMU00 */
629  CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */
630  CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX0 */
631  CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */
632  CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */
633  CLKDEV_DEV_ID("sh_mobile_meram.0", &mstp_clks[MSTP113]), /* MERAM */
634  CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */
635  CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[MSTP101]), /* VPU */
636  CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
637  CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[MSTP223]), /* SPU2DSP0 */
638  CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[MSTP223]), /* SPU2DSP1 */
639  CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* DMAC1 */
640  CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]), /* DMAC2 */
641  CLKDEV_DEV_ID("sh-dma-engine.2", &mstp_clks[MSTP216]), /* DMAC3 */
642  CLKDEV_DEV_ID("sh-dma-engine.3", &mstp_clks[MSTP214]), /* USB-DMAC0 */
643  CLKDEV_DEV_ID("spi_sh_msiof.1", &mstp_clks[MSTP208]), /* MSIOF1 */
644  CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
645  CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP206]), /* SCIFB */
646  CLKDEV_DEV_ID("spi_sh_msiof.2", &mstp_clks[MSTP205]), /* MSIOF2 */
647  CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
648  CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
649  CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
650  CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
651  CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
652  CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */
653  CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */
654  CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USB0 */
655  CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP322]), /* USB0 */
656  CLKDEV_DEV_ID("renesas_usbhs.0", &mstp_clks[MSTP322]), /* USB0 */
657  CLKDEV_DEV_ID("sh_flctl.0", &mstp_clks[MSTP315]), /* FLCTL */
658  CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
659  CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
660  CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMC */
661  CLKDEV_DEV_ID("sh-mipi-dsi.1", &mstp_clks[MSTP423]), /* DSITX1 */
662  CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]), /* SDHI2 */
663  CLKDEV_DEV_ID("sh-mobile-hdmi", &mstp_clks[MSTP413]), /* HDMI */
664  CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* IIC3 */
665  CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* IIC4 */
666  CLKDEV_DEV_ID("sh-dma-engine.4", &mstp_clks[MSTP407]), /* USB-DMAC1 */
667  CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */
668  CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */
669  CLKDEV_DEV_ID("renesas_usbhs.1", &mstp_clks[MSTP406]), /* USB1 */
670  CLKDEV_DEV_ID("sh_cmt.4", &mstp_clks[MSTP405]), /* CMT4 */
671  CLKDEV_DEV_ID("sh_cmt.3", &mstp_clks[MSTP404]), /* CMT3 */
672  CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
673  CLKDEV_DEV_ID("sh_cmt.2", &mstp_clks[MSTP400]), /* CMT2 */
674 
675  CLKDEV_ICK_ID("hdmi", "sh_mobile_lcdc_fb.1",
676  &div6_reparent_clks[DIV6_HDMI]),
677  CLKDEV_ICK_ID("ick", "sh-mobile-hdmi", &div6_reparent_clks[DIV6_HDMI]),
678  CLKDEV_ICK_ID("icka", "sh_fsi2", &div6_reparent_clks[DIV6_FSIA]),
679  CLKDEV_ICK_ID("ickb", "sh_fsi2", &div6_reparent_clks[DIV6_FSIB]),
680  CLKDEV_ICK_ID("spu2", "sh_fsi2", &mstp_clks[MSTP223]),
681 };
682 
684 {
685  int k, ret = 0;
686 
687  /* make sure MSTP bits on the RT/SH4AL-DSP side are off */
688  __raw_writel(0xe4ef8087, RMSTPCR0);
689  __raw_writel(0xffffffff, RMSTPCR1);
690  __raw_writel(0x37c7f7ff, RMSTPCR2);
691  __raw_writel(0xffffffff, RMSTPCR3);
692  __raw_writel(0xffe0fffd, RMSTPCR4);
693 
694  for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
695  ret = clk_register(main_clks[k]);
696 
697  if (!ret)
698  ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
699 
700  if (!ret)
701  ret = sh_clk_div6_register(div6_clks, DIV6_NR);
702 
703  if (!ret)
704  ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_REPARENT_NR);
705 
706  if (!ret)
707  ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
708 
709  for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
710  ret = clk_register(late_main_clks[k]);
711 
712  clkdev_add_table(lookups, ARRAY_SIZE(lookups));
713 
714  if (!ret)
716  else
717  panic("failed to setup sh7372 clocks\n");
718 
719 }