~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/arm/mach-shmobile/clock-sh7372.c

Version: ~ [ linux-5.5-rc7 ] ~ [ linux-5.4.13 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.97 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.166 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.210 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.210 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.81 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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          0xe6150000
 28 #define FRQCRB          0xe6150004
 29 #define FRQCRC          0xe61500e0
 30 #define FRQCRD          0xe61500e4
 31 #define VCLKCR1         0xe6150008
 32 #define VCLKCR2         0xe615000c
 33 #define VCLKCR3         0xe615001c
 34 #define FMSICKCR        0xe6150010
 35 #define FMSOCKCR        0xe6150014
 36 #define FSIACKCR        0xe6150018
 37 #define FSIBCKCR        0xe6150090
 38 #define SUBCKCR         0xe6150080
 39 #define SPUCKCR         0xe6150084
 40 #define VOUCKCR         0xe6150088
 41 #define HDMICKCR        0xe6150094
 42 #define DSITCKCR        0xe6150060
 43 #define DSI0PCKCR       0xe6150064
 44 #define DSI1PCKCR       0xe6150098
 45 #define PLLC01CR        0xe6150028
 46 #define PLLC2CR         0xe615002c
 47 #define RMSTPCR0        0xe6150110
 48 #define RMSTPCR1        0xe6150114
 49 #define RMSTPCR2        0xe6150118
 50 #define RMSTPCR3        0xe615011c
 51 #define RMSTPCR4        0xe6150120
 52 #define SMSTPCR0        0xe6150130
 53 #define SMSTPCR1        0xe6150134
 54 #define SMSTPCR2        0xe6150138
 55 #define SMSTPCR3        0xe615013c
 56 #define SMSTPCR4        0xe6150140
 57 
 58 #define FSIDIVA         0xFE1F8000
 59 #define FSIDIVB         0xFE1F8008
 60 
 61 /* Platforms must set frequency on their DV_CLKI pin */
 62 struct clk sh7372_dv_clki_clk = {
 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  */
 74 struct clk sh7372_extal1_clk = {
 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  */
 82 struct clk sh7372_extal2_clk = {
 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 */
 97 struct clk sh7372_dv_clki_div2_clk = {
 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,
161         [2] = &sh7372_dv_clki_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[] = {
305         &sh7372_dv_clki_clk,
306         &r_clk,
307         &sh7372_extal1_clk,
308         &sh7372_extal2_clk,
309         &sh7372_dv_clki_div2_clk,
310         &extal1_div2_clk,
311         &extal2_div2_clk,
312         &extal2_div4_clk,
313         &pllc0_clk,
314         &pllc1_clk,
315         &pllc1_div2_clk,
316         &sh7372_pllc2_clk,
317         &sh7372_fsiack_clk,
318         &sh7372_fsibck_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 
344 enum { DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_CSIR,
345        DIV4_ZTR, DIV4_ZT, DIV4_ZX, DIV4_HP,
346        DIV4_ISPB, DIV4_S, DIV4_ZB, DIV4_ZB3, DIV4_CP,
347        DIV4_DDRP, DIV4_NR };
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 
370 enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_FMSI, DIV6_FMSO,
371        DIV6_SUB, DIV6_SPU,
372        DIV6_VOU, DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P,
373        DIV6_NR };
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 
389 enum { DIV6_HDMI, DIV6_FSIA, DIV6_FSIB, DIV6_REPARENT_NR };
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] = {
414         [DIV6_HDMI] = SH_CLK_DIV6_EXT(HDMICKCR, 0,
415                                       hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2),
416         [DIV6_FSIA] = SH_CLK_DIV6_EXT(FSIACKCR, 0,
417                                       fsiackcr_parent, ARRAY_SIZE(fsiackcr_parent), 6, 2),
418         [DIV6_FSIB] = SH_CLK_DIV6_EXT(FSIBCKCR, 0,
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[] = {
502         &sh7372_fsidiva_clk,
503         &sh7372_fsidivb_clk,
504 };
505 
506 enum { MSTP001, MSTP000,
507        MSTP131, MSTP130,
508        MSTP129, MSTP128, MSTP127, MSTP126, MSTP125,
509        MSTP118, MSTP117, MSTP116, MSTP113,
510        MSTP106, MSTP101, MSTP100,
511        MSTP223,
512        MSTP218, MSTP217, MSTP216, MSTP214, MSTP208, MSTP207,
513        MSTP206, MSTP205, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
514         MSTP328, MSTP323, MSTP322, MSTP315, MSTP314, MSTP313, MSTP312,
515        MSTP423, MSTP415, MSTP413, MSTP411, MSTP410, MSTP407, MSTP406,
516        MSTP405, MSTP404, MSTP403, MSTP400,
517        MSTP_NR };
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 
683 void __init sh7372_clock_init(void)
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_mstp32_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)
715                 shmobile_clk_init();
716         else
717                 panic("failed to setup sh7372 clocks\n");
718 
719 }
720 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp