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

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

Version: ~ [ linux-5.8-rc4 ] ~ [ linux-5.7.7 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.50 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.131 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.187 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.229 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.229 ] ~ [ 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.85 ] ~ [ 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-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  * R8A7740 processor support
  3  *
  4  * Copyright (C) 2011  Renesas Solutions Corp.
  5  * Copyright (C) 2011  Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
  6  *
  7  * This program is free software; you can redistribute it and/or modify
  8  * it under the terms of the GNU General Public License as published by
  9  * the Free Software Foundation; either version 2 of the License
 10  *
 11  * This program is distributed in the hope that it will be useful,
 12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 14  * GNU General Public License for more details.
 15  */
 16 #include <linux/init.h>
 17 #include <linux/kernel.h>
 18 #include <linux/io.h>
 19 #include <linux/sh_clk.h>
 20 #include <linux/clkdev.h>
 21 
 22 #include "clock.h"
 23 #include "common.h"
 24 #include "r8a7740.h"
 25 
 26 /*
 27  *        |  MDx  |  XTAL1/EXTAL1   |  System   | EXTALR |
 28  *  Clock |-------+-----------------+  clock    | 32.768 |   RCLK
 29  *  Mode  | 2/1/0 | src         MHz |  source   |  KHz   |  source
 30  * -------+-------+-----------------+-----------+--------+----------
 31  *    0   | 0 0 0 | External  20~50 | XTAL1     |    O   |  EXTALR
 32  *    1   | 0 0 1 | Crystal   20~30 | XTAL1     |    O   |  EXTALR
 33  *    2   | 0 1 0 | External  40~50 | XTAL1 / 2 |    O   |  EXTALR
 34  *    3   | 0 1 1 | Crystal   40~50 | XTAL1 / 2 |    O   |  EXTALR
 35  *    4   | 1 0 0 | External  20~50 | XTAL1     |    x   |  XTAL1 / 1024
 36  *    5   | 1 0 1 | Crystal   20~30 | XTAL1     |    x   |  XTAL1 / 1024
 37  *    6   | 1 1 0 | External  40~50 | XTAL1 / 2 |    x   |  XTAL1 / 2048
 38  *    7   | 1 1 1 | Crystal   40~50 | XTAL1 / 2 |    x   |  XTAL1 / 2048
 39  */
 40 
 41 /* CPG registers */
 42 #define FRQCRA          IOMEM(0xe6150000)
 43 #define FRQCRB          IOMEM(0xe6150004)
 44 #define VCLKCR1         IOMEM(0xE6150008)
 45 #define VCLKCR2         IOMEM(0xE615000c)
 46 #define FRQCRC          IOMEM(0xe61500e0)
 47 #define FSIACKCR        IOMEM(0xe6150018)
 48 #define PLLC01CR        IOMEM(0xe6150028)
 49 
 50 #define SUBCKCR         IOMEM(0xe6150080)
 51 #define USBCKCR         IOMEM(0xe615008c)
 52 
 53 #define MSTPSR0         IOMEM(0xe6150030)
 54 #define MSTPSR1         IOMEM(0xe6150038)
 55 #define MSTPSR2         IOMEM(0xe6150040)
 56 #define MSTPSR3         IOMEM(0xe6150048)
 57 #define MSTPSR4         IOMEM(0xe615004c)
 58 #define FSIBCKCR        IOMEM(0xe6150090)
 59 #define HDMICKCR        IOMEM(0xe6150094)
 60 #define SMSTPCR0        IOMEM(0xe6150130)
 61 #define SMSTPCR1        IOMEM(0xe6150134)
 62 #define SMSTPCR2        IOMEM(0xe6150138)
 63 #define SMSTPCR3        IOMEM(0xe615013c)
 64 #define SMSTPCR4        IOMEM(0xe6150140)
 65 
 66 #define FSIDIVA         IOMEM(0xFE1F8000)
 67 #define FSIDIVB         IOMEM(0xFE1F8008)
 68 
 69 /* Fixed 32 KHz root clock from EXTALR pin */
 70 static struct clk extalr_clk = {
 71         .rate   = 32768,
 72 };
 73 
 74 /*
 75  * 25MHz default rate for the EXTAL1 root input clock.
 76  * If needed, reset this with clk_set_rate() from the platform code.
 77  */
 78 static struct clk extal1_clk = {
 79         .rate   = 25000000,
 80 };
 81 
 82 /*
 83  * 48MHz default rate for the EXTAL2 root input clock.
 84  * If needed, reset this with clk_set_rate() from the platform code.
 85  */
 86 static struct clk extal2_clk = {
 87         .rate   = 48000000,
 88 };
 89 
 90 /*
 91  * 27MHz default rate for the DV_CLKI root input clock.
 92  * If needed, reset this with clk_set_rate() from the platform code.
 93  */
 94 static struct clk dv_clk = {
 95         .rate   = 27000000,
 96 };
 97 
 98 SH_CLK_RATIO(div2,      1, 2);
 99 SH_CLK_RATIO(div1k,     1, 1024);
100 
101 SH_FIXED_RATIO_CLK(extal1_div2_clk,     extal1_clk,             div2);
102 SH_FIXED_RATIO_CLK(extal1_div1024_clk,  extal1_clk,             div1k);
103 SH_FIXED_RATIO_CLK(extal1_div2048_clk,  extal1_div2_clk,        div1k);
104 SH_FIXED_RATIO_CLK(extal2_div2_clk,     extal2_clk,             div2);
105 
106 static struct sh_clk_ops followparent_clk_ops = {
107         .recalc = followparent_recalc,
108 };
109 
110 /* Main clock */
111 static struct clk system_clk = {
112         .ops    = &followparent_clk_ops,
113 };
114 
115 SH_FIXED_RATIO_CLK(system_div2_clk, system_clk, div2);
116 
117 /* r_clk */
118 static struct clk r_clk = {
119         .ops    = &followparent_clk_ops,
120 };
121 
122 /* PLLC0/PLLC1 */
123 static unsigned long pllc01_recalc(struct clk *clk)
124 {
125         unsigned long mult = 1;
126 
127         if (__raw_readl(PLLC01CR) & (1 << 14))
128                 mult = ((__raw_readl(clk->enable_reg) >> 24) & 0x7f) + 1;
129 
130         return clk->parent->rate * mult;
131 }
132 
133 static struct sh_clk_ops pllc01_clk_ops = {
134         .recalc         = pllc01_recalc,
135 };
136 
137 static struct clk pllc0_clk = {
138         .ops            = &pllc01_clk_ops,
139         .flags          = CLK_ENABLE_ON_INIT,
140         .parent         = &system_clk,
141         .enable_reg     = (void __iomem *)FRQCRC,
142 };
143 
144 static struct clk pllc1_clk = {
145         .ops            = &pllc01_clk_ops,
146         .flags          = CLK_ENABLE_ON_INIT,
147         .parent         = &system_div2_clk,
148         .enable_reg     = (void __iomem *)FRQCRA,
149 };
150 
151 /* PLLC1 / 2 */
152 SH_FIXED_RATIO_CLK(pllc1_div2_clk, pllc1_clk, div2);
153 
154 /* USB clock */
155 /*
156  * USBCKCR is controlling usb24 clock
157  * bit[7] : parent clock
158  * bit[6] : clock divide rate
159  * And this bit[7] is used as a "usb24s" from other devices.
160  * (Video clock / Sub clock / SPU clock)
161  * You can controll this clock as a below.
162  *
163  * struct clk *usb24    = clk_get(dev,  "usb24");
164  * struct clk *usb24s   = clk_get(NULL, "usb24s");
165  * struct clk *system   = clk_get(NULL, "system_clk");
166  * int rate = clk_get_rate(system);
167  *
168  * clk_set_parent(usb24s, system);  // for bit[7]
169  * clk_set_rate(usb24, rate / 2);   // for bit[6]
170  */
171 static struct clk *usb24s_parents[] = {
172         [0] = &system_clk,
173         [1] = &extal2_clk
174 };
175 
176 static int usb24s_enable(struct clk *clk)
177 {
178         __raw_writel(__raw_readl(USBCKCR) & ~(1 << 8), USBCKCR);
179 
180         return 0;
181 }
182 
183 static void usb24s_disable(struct clk *clk)
184 {
185         __raw_writel(__raw_readl(USBCKCR) | (1 << 8), USBCKCR);
186 }
187 
188 static int usb24s_set_parent(struct clk *clk, struct clk *parent)
189 {
190         int i, ret;
191         u32 val;
192 
193         if (!clk->parent_table || !clk->parent_num)
194                 return -EINVAL;
195 
196         /* Search the parent */
197         for (i = 0; i < clk->parent_num; i++)
198                 if (clk->parent_table[i] == parent)
199                         break;
200 
201         if (i == clk->parent_num)
202                 return -ENODEV;
203 
204         ret = clk_reparent(clk, parent);
205         if (ret < 0)
206                 return ret;
207 
208         val = __raw_readl(USBCKCR);
209         val &= ~(1 << 7);
210         val |= i << 7;
211         __raw_writel(val, USBCKCR);
212 
213         return 0;
214 }
215 
216 static struct sh_clk_ops usb24s_clk_ops = {
217         .recalc         = followparent_recalc,
218         .enable         = usb24s_enable,
219         .disable        = usb24s_disable,
220         .set_parent     = usb24s_set_parent,
221 };
222 
223 static struct clk usb24s_clk = {
224         .ops            = &usb24s_clk_ops,
225         .parent_table   = usb24s_parents,
226         .parent_num     = ARRAY_SIZE(usb24s_parents),
227         .parent         = &system_clk,
228 };
229 
230 static unsigned long usb24_recalc(struct clk *clk)
231 {
232         return clk->parent->rate /
233                 ((__raw_readl(USBCKCR) & (1 << 6)) ? 1 : 2);
234 };
235 
236 static int usb24_set_rate(struct clk *clk, unsigned long rate)
237 {
238         u32 val;
239 
240         /* closer to which ? parent->rate or parent->rate/2 */
241         val = __raw_readl(USBCKCR);
242         val &= ~(1 << 6);
243         val |= (rate > (clk->parent->rate / 4) * 3) << 6;
244         __raw_writel(val, USBCKCR);
245 
246         return 0;
247 }
248 
249 static struct sh_clk_ops usb24_clk_ops = {
250         .recalc         = usb24_recalc,
251         .set_rate       = usb24_set_rate,
252 };
253 
254 static struct clk usb24_clk = {
255         .ops            = &usb24_clk_ops,
256         .parent         = &usb24s_clk,
257 };
258 
259 /* External FSIACK/FSIBCK clock */
260 static struct clk fsiack_clk = {
261 };
262 
263 static struct clk fsibck_clk = {
264 };
265 
266 static struct clk *main_clks[] = {
267         &extalr_clk,
268         &extal1_clk,
269         &extal2_clk,
270         &extal1_div2_clk,
271         &extal1_div1024_clk,
272         &extal1_div2048_clk,
273         &extal2_div2_clk,
274         &dv_clk,
275         &system_clk,
276         &system_div2_clk,
277         &r_clk,
278         &pllc0_clk,
279         &pllc1_clk,
280         &pllc1_div2_clk,
281         &usb24s_clk,
282         &usb24_clk,
283         &fsiack_clk,
284         &fsibck_clk,
285 };
286 
287 /* DIV4 clocks */
288 static void div4_kick(struct clk *clk)
289 {
290         unsigned long value;
291 
292         /* set KICK bit in FRQCRB to update hardware setting */
293         value = __raw_readl(FRQCRB);
294         value |= (1 << 31);
295         __raw_writel(value, FRQCRB);
296 }
297 
298 static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
299                           24, 32, 36, 48, 0, 72, 96, 0 };
300 
301 static struct clk_div_mult_table div4_div_mult_table = {
302         .divisors = divisors,
303         .nr_divisors = ARRAY_SIZE(divisors),
304 };
305 
306 static struct clk_div4_table div4_table = {
307         .div_mult_table = &div4_div_mult_table,
308         .kick = div4_kick,
309 };
310 
311 enum {
312         DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_HP,
313         DIV4_HPP, DIV4_USBP, DIV4_S, DIV4_ZB, DIV4_M3, DIV4_CP,
314         DIV4_NR
315 };
316 
317 static struct clk div4_clks[DIV4_NR] = {
318         [DIV4_I]        = SH_CLK_DIV4(&pllc1_clk, FRQCRA, 20, 0x6fff, CLK_ENABLE_ON_INIT),
319         [DIV4_ZG]       = SH_CLK_DIV4(&pllc1_clk, FRQCRA, 16, 0x6fff, CLK_ENABLE_ON_INIT),
320         [DIV4_B]        = SH_CLK_DIV4(&pllc1_clk, FRQCRA,  8, 0x6fff, CLK_ENABLE_ON_INIT),
321         [DIV4_M1]       = SH_CLK_DIV4(&pllc1_clk, FRQCRA,  4, 0x6fff, CLK_ENABLE_ON_INIT),
322         [DIV4_HP]       = SH_CLK_DIV4(&pllc1_clk, FRQCRB,  4, 0x6fff, 0),
323         [DIV4_HPP]      = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 20, 0x6fff, 0),
324         [DIV4_USBP]     = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 16, 0x6fff, 0),
325         [DIV4_S]        = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 12, 0x6fff, 0),
326         [DIV4_ZB]       = SH_CLK_DIV4(&pllc1_clk, FRQCRC,  8, 0x6fff, 0),
327         [DIV4_M3]       = SH_CLK_DIV4(&pllc1_clk, FRQCRC,  4, 0x6fff, 0),
328         [DIV4_CP]       = SH_CLK_DIV4(&pllc1_clk, FRQCRC,  0, 0x6fff, 0),
329 };
330 
331 /* DIV6 reparent */
332 enum {
333         DIV6_HDMI,
334         DIV6_VCLK1, DIV6_VCLK2,
335         DIV6_FSIA, DIV6_FSIB,
336         DIV6_REPARENT_NR,
337 };
338 
339 static struct clk *hdmi_parent[] = {
340         [0] = &pllc1_div2_clk,
341         [1] = &system_clk,
342         [2] = &dv_clk
343 };
344 
345 static struct clk *vclk_parents[8] = {
346         [0] = &pllc1_div2_clk,
347         [2] = &dv_clk,
348         [3] = &usb24s_clk,
349         [4] = &extal1_div2_clk,
350         [5] = &extalr_clk,
351 };
352 
353 static struct clk *fsia_parents[] = {
354         [0] = &pllc1_div2_clk,
355         [1] = &fsiack_clk, /* external clock */
356 };
357 
358 static struct clk *fsib_parents[] = {
359         [0] = &pllc1_div2_clk,
360         [1] = &fsibck_clk, /* external clock */
361 };
362 
363 static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = {
364         [DIV6_HDMI] = SH_CLK_DIV6_EXT(HDMICKCR, 0,
365                                       hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2),
366         [DIV6_VCLK1] = SH_CLK_DIV6_EXT(VCLKCR1, 0,
367                                        vclk_parents, ARRAY_SIZE(vclk_parents), 12, 3),
368         [DIV6_VCLK2] = SH_CLK_DIV6_EXT(VCLKCR2, 0,
369                                        vclk_parents, ARRAY_SIZE(vclk_parents), 12, 3),
370         [DIV6_FSIA] = SH_CLK_DIV6_EXT(FSIACKCR, 0,
371                                       fsia_parents, ARRAY_SIZE(fsia_parents), 6, 2),
372         [DIV6_FSIB] = SH_CLK_DIV6_EXT(FSIBCKCR, 0,
373                                       fsib_parents, ARRAY_SIZE(fsib_parents), 6, 2),
374 };
375 
376 /* DIV6 clocks */
377 enum {
378         DIV6_SUB,
379         DIV6_NR
380 };
381 
382 static struct clk div6_clks[DIV6_NR] = {
383         [DIV6_SUB]      = SH_CLK_DIV6(&pllc1_div2_clk, SUBCKCR, 0),
384 };
385 
386 /* HDMI1/2 clock */
387 static unsigned long hdmi12_recalc(struct clk *clk)
388 {
389         u32 val = __raw_readl(HDMICKCR);
390         int shift = (int)clk->priv;
391 
392         val >>= shift;
393         val &= 0x3;
394 
395         return clk->parent->rate / (1 << val);
396 };
397 
398 static int hdmi12_set_rate(struct clk *clk, unsigned long rate)
399 {
400         u32 val, mask;
401         int i, shift;
402 
403         for (i = 0; i < 3; i++)
404                 if (rate == clk->parent->rate / (1 << i))
405                         goto find;
406         return -ENODEV;
407 
408 find:
409         shift = (int)clk->priv;
410 
411         val = __raw_readl(HDMICKCR);
412         mask = ~(0x3 << shift);
413         val = (val & mask) | i << shift;
414         __raw_writel(val, HDMICKCR);
415 
416         return 0;
417 };
418 
419 static struct sh_clk_ops hdmi12_clk_ops = {
420         .recalc         = hdmi12_recalc,
421         .set_rate       = hdmi12_set_rate,
422 };
423 
424 static struct clk hdmi1_clk = {
425         .ops            = &hdmi12_clk_ops,
426         .priv           = (void *)9,
427         .parent         = &div6_reparent_clks[DIV6_HDMI],  /* late install */
428 };
429 
430 static struct clk hdmi2_clk = {
431         .ops            = &hdmi12_clk_ops,
432         .priv           = (void *)11,
433         .parent         = &div6_reparent_clks[DIV6_HDMI], /* late install */
434 };
435 
436 static struct clk *late_main_clks[] = {
437         &hdmi1_clk,
438         &hdmi2_clk,
439 };
440 
441 /* FSI DIV */
442 enum { FSIDIV_A, FSIDIV_B, FSIDIV_REPARENT_NR };
443 
444 static struct clk fsidivs[] = {
445         [FSIDIV_A] = SH_CLK_FSIDIV(FSIDIVA, &div6_reparent_clks[DIV6_FSIA]),
446         [FSIDIV_B] = SH_CLK_FSIDIV(FSIDIVB, &div6_reparent_clks[DIV6_FSIB]),
447 };
448 
449 /* MSTP */
450 enum {
451         MSTP128, MSTP127, MSTP125,
452         MSTP116, MSTP111, MSTP100, MSTP117,
453 
454         MSTP230, MSTP229,
455         MSTP222,
456         MSTP218, MSTP217, MSTP216, MSTP214,
457         MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
458 
459         MSTP329, MSTP328, MSTP323, MSTP320,
460         MSTP314, MSTP313, MSTP312,
461         MSTP309, MSTP304,
462 
463         MSTP416, MSTP415, MSTP407, MSTP406,
464 
465         MSTP_NR
466 };
467 
468 static struct clk mstp_clks[MSTP_NR] = {
469         [MSTP128] = SH_CLK_MSTP32(&div4_clks[DIV4_S],   SMSTPCR1, 28, 0), /* CEU21 */
470         [MSTP127] = SH_CLK_MSTP32(&div4_clks[DIV4_S],   SMSTPCR1, 27, 0), /* CEU20 */
471         [MSTP125] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
472         [MSTP117] = SH_CLK_MSTP32(&div4_clks[DIV4_B],   SMSTPCR1, 17, 0), /* LCDC1 */
473         [MSTP116] = SH_CLK_MSTP32(&div4_clks[DIV4_HPP], SMSTPCR1, 16, 0), /* IIC0 */
474         [MSTP111] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 11, 0), /* TMU1 */
475         [MSTP100] = SH_CLK_MSTP32(&div4_clks[DIV4_B],   SMSTPCR1,  0, 0), /* LCDC0 */
476 
477         [MSTP230] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 30, 0), /* SCIFA6 */
478         [MSTP229] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR2, 29, 0), /* INTCA */
479         [MSTP222] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 22, 0), /* SCIFA7 */
480         [MSTP218] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR2, 18, 0), /* DMAC1 */
481         [MSTP217] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR2, 17, 0), /* DMAC2 */
482         [MSTP216] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR2, 16, 0), /* DMAC3 */
483         [MSTP214] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR2, 14, 0), /* USBDMAC */
484         [MSTP207] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2,  7, 0), /* SCIFA5 */
485         [MSTP206] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2,  6, 0), /* SCIFB */
486         [MSTP204] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2,  4, 0), /* SCIFA0 */
487         [MSTP203] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2,  3, 0), /* SCIFA1 */
488         [MSTP202] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2,  2, 0), /* SCIFA2 */
489         [MSTP201] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2,  1, 0), /* SCIFA3 */
490         [MSTP200] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2,  0, 0), /* SCIFA4 */
491 
492         [MSTP329] = SH_CLK_MSTP32(&r_clk,               SMSTPCR3, 29, 0), /* CMT10 */
493         [MSTP328] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR3, 28, 0), /* FSI */
494         [MSTP323] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
495         [MSTP320] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR3, 20, 0), /* USBF */
496         [MSTP314] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR3, 14, 0), /* SDHI0 */
497         [MSTP313] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR3, 13, 0), /* SDHI1 */
498         [MSTP312] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR3, 12, 0), /* MMC */
499         [MSTP309] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR3,  9, 0), /* GEther */
500         [MSTP304] = SH_CLK_MSTP32(&div4_clks[DIV4_CP],  SMSTPCR3,  4, 0), /* TPU0 */
501 
502         [MSTP416] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR4, 16, 0), /* USBHOST */
503         [MSTP415] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR4, 15, 0), /* SDHI2 */
504         [MSTP407] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR4,  7, 0), /* USB-Func */
505         [MSTP406] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR4,  6, 0), /* USB Phy */
506 };
507 
508 static struct clk_lookup lookups[] = {
509         /* main clocks */
510         CLKDEV_CON_ID("extalr",                 &extalr_clk),
511         CLKDEV_CON_ID("extal1",                 &extal1_clk),
512         CLKDEV_CON_ID("extal2",                 &extal2_clk),
513         CLKDEV_CON_ID("extal1_div2",            &extal1_div2_clk),
514         CLKDEV_CON_ID("extal1_div1024",         &extal1_div1024_clk),
515         CLKDEV_CON_ID("extal1_div2048",         &extal1_div2048_clk),
516         CLKDEV_CON_ID("extal2_div2",            &extal2_div2_clk),
517         CLKDEV_CON_ID("dv_clk",                 &dv_clk),
518         CLKDEV_CON_ID("system_clk",             &system_clk),
519         CLKDEV_CON_ID("system_div2_clk",        &system_div2_clk),
520         CLKDEV_CON_ID("r_clk",                  &r_clk),
521         CLKDEV_CON_ID("pllc0_clk",              &pllc0_clk),
522         CLKDEV_CON_ID("pllc1_clk",              &pllc1_clk),
523         CLKDEV_CON_ID("pllc1_div2_clk",         &pllc1_div2_clk),
524         CLKDEV_CON_ID("usb24s",                 &usb24s_clk),
525         CLKDEV_CON_ID("hdmi1",                  &hdmi1_clk),
526         CLKDEV_CON_ID("hdmi2",                  &hdmi2_clk),
527         CLKDEV_CON_ID("video1",                 &div6_reparent_clks[DIV6_VCLK1]),
528         CLKDEV_CON_ID("video2",                 &div6_reparent_clks[DIV6_VCLK2]),
529         CLKDEV_CON_ID("fsiack",                 &fsiack_clk),
530         CLKDEV_CON_ID("fsibck",                 &fsibck_clk),
531 
532         /* DIV4 clocks */
533         CLKDEV_CON_ID("i_clk",                  &div4_clks[DIV4_I]),
534         CLKDEV_CON_ID("zg_clk",                 &div4_clks[DIV4_ZG]),
535         CLKDEV_CON_ID("b_clk",                  &div4_clks[DIV4_B]),
536         CLKDEV_CON_ID("m1_clk",                 &div4_clks[DIV4_M1]),
537         CLKDEV_CON_ID("hp_clk",                 &div4_clks[DIV4_HP]),
538         CLKDEV_CON_ID("hpp_clk",                &div4_clks[DIV4_HPP]),
539         CLKDEV_CON_ID("s_clk",                  &div4_clks[DIV4_S]),
540         CLKDEV_CON_ID("zb_clk",                 &div4_clks[DIV4_ZB]),
541         CLKDEV_CON_ID("m3_clk",                 &div4_clks[DIV4_M3]),
542         CLKDEV_CON_ID("cp_clk",                 &div4_clks[DIV4_CP]),
543 
544         /* DIV6 clocks */
545         CLKDEV_CON_ID("sub_clk",                &div6_clks[DIV6_SUB]),
546 
547         /* MSTP32 clocks */
548         CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0",    &mstp_clks[MSTP100]),
549         CLKDEV_DEV_ID("i2c-sh_mobile.0",        &mstp_clks[MSTP116]),
550         CLKDEV_DEV_ID("fff20000.i2c",           &mstp_clks[MSTP116]),
551         CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1",    &mstp_clks[MSTP117]),
552         CLKDEV_DEV_ID("sh_mobile_ceu.0",        &mstp_clks[MSTP127]),
553         CLKDEV_DEV_ID("sh_mobile_ceu.1",        &mstp_clks[MSTP128]),
554 
555         CLKDEV_DEV_ID("sh-sci.4",               &mstp_clks[MSTP200]),
556         CLKDEV_DEV_ID("e6c80000.serial",        &mstp_clks[MSTP200]),
557         CLKDEV_DEV_ID("sh-sci.3",               &mstp_clks[MSTP201]),
558         CLKDEV_DEV_ID("e6c70000.serial",        &mstp_clks[MSTP201]),
559         CLKDEV_DEV_ID("sh-sci.2",               &mstp_clks[MSTP202]),
560         CLKDEV_DEV_ID("e6c60000.serial",        &mstp_clks[MSTP202]),
561         CLKDEV_DEV_ID("sh-sci.1",               &mstp_clks[MSTP203]),
562         CLKDEV_DEV_ID("e6c50000.serial",        &mstp_clks[MSTP203]),
563         CLKDEV_DEV_ID("sh-sci.0",               &mstp_clks[MSTP204]),
564         CLKDEV_DEV_ID("e6c40000.serial",        &mstp_clks[MSTP204]),
565         CLKDEV_DEV_ID("sh-sci.8",               &mstp_clks[MSTP206]),
566         CLKDEV_DEV_ID("e6c30000.serial",        &mstp_clks[MSTP206]),
567         CLKDEV_DEV_ID("sh-sci.5",               &mstp_clks[MSTP207]),
568         CLKDEV_DEV_ID("e6cb0000.serial",        &mstp_clks[MSTP207]),
569         CLKDEV_DEV_ID("sh-dma-engine.3",        &mstp_clks[MSTP214]),
570         CLKDEV_DEV_ID("sh-dma-engine.2",        &mstp_clks[MSTP216]),
571         CLKDEV_DEV_ID("sh-dma-engine.1",        &mstp_clks[MSTP217]),
572         CLKDEV_DEV_ID("sh-dma-engine.0",        &mstp_clks[MSTP218]),
573         CLKDEV_DEV_ID("sh-sci.7",               &mstp_clks[MSTP222]),
574         CLKDEV_DEV_ID("e6cd0000.serial",        &mstp_clks[MSTP222]),
575         CLKDEV_DEV_ID("renesas_intc_irqpin.0",  &mstp_clks[MSTP229]),
576         CLKDEV_DEV_ID("renesas_intc_irqpin.1",  &mstp_clks[MSTP229]),
577         CLKDEV_DEV_ID("renesas_intc_irqpin.2",  &mstp_clks[MSTP229]),
578         CLKDEV_DEV_ID("renesas_intc_irqpin.3",  &mstp_clks[MSTP229]),
579         CLKDEV_DEV_ID("sh-sci.6",               &mstp_clks[MSTP230]),
580         CLKDEV_DEV_ID("e6cc0000.serial",        &mstp_clks[MSTP230]),
581 
582         CLKDEV_DEV_ID("sh_fsi2",                &mstp_clks[MSTP328]),
583         CLKDEV_DEV_ID("fe1f0000.sound",         &mstp_clks[MSTP328]),
584         CLKDEV_DEV_ID("i2c-sh_mobile.1",        &mstp_clks[MSTP323]),
585         CLKDEV_DEV_ID("e6c20000.i2c",           &mstp_clks[MSTP323]),
586         CLKDEV_DEV_ID("renesas_usbhs",          &mstp_clks[MSTP320]),
587         CLKDEV_DEV_ID("sh_mobile_sdhi.0",       &mstp_clks[MSTP314]),
588         CLKDEV_DEV_ID("e6850000.sd",            &mstp_clks[MSTP314]),
589         CLKDEV_DEV_ID("sh_mobile_sdhi.1",       &mstp_clks[MSTP313]),
590         CLKDEV_DEV_ID("e6860000.sd",            &mstp_clks[MSTP313]),
591         CLKDEV_DEV_ID("sh_mmcif",               &mstp_clks[MSTP312]),
592         CLKDEV_DEV_ID("e6bd0000.mmc",           &mstp_clks[MSTP312]),
593         CLKDEV_DEV_ID("r8a7740-gether",         &mstp_clks[MSTP309]),
594         CLKDEV_DEV_ID("e9a00000.ethernet",      &mstp_clks[MSTP309]),
595         CLKDEV_DEV_ID("renesas-tpu-pwm",        &mstp_clks[MSTP304]),
596         CLKDEV_DEV_ID("e6600000.pwm",           &mstp_clks[MSTP304]),
597 
598         CLKDEV_DEV_ID("sh_mobile_sdhi.2",       &mstp_clks[MSTP415]),
599         CLKDEV_DEV_ID("e6870000.sd",            &mstp_clks[MSTP415]),
600 
601         /* ICK */
602         CLKDEV_ICK_ID("fck",    "sh-tmu.1",             &mstp_clks[MSTP111]),
603         CLKDEV_ICK_ID("fck",    "fff90000.timer",       &mstp_clks[MSTP111]),
604         CLKDEV_ICK_ID("fck",    "sh-tmu.0",             &mstp_clks[MSTP125]),
605         CLKDEV_ICK_ID("fck",    "fff80000.timer",       &mstp_clks[MSTP125]),
606         CLKDEV_ICK_ID("fck",    "sh-cmt-48.1",          &mstp_clks[MSTP329]),
607         CLKDEV_ICK_ID("fck",    "e6138000.timer",       &mstp_clks[MSTP329]),
608         CLKDEV_ICK_ID("host",   "renesas_usbhs",        &mstp_clks[MSTP416]),
609         CLKDEV_ICK_ID("func",   "renesas_usbhs",        &mstp_clks[MSTP407]),
610         CLKDEV_ICK_ID("phy",    "renesas_usbhs",        &mstp_clks[MSTP406]),
611         CLKDEV_ICK_ID("pci",    "renesas_usbhs",        &div4_clks[DIV4_USBP]),
612         CLKDEV_ICK_ID("usb24",  "renesas_usbhs",        &usb24_clk),
613         CLKDEV_ICK_ID("ick",    "sh-mobile-hdmi",       &div6_reparent_clks[DIV6_HDMI]),
614 
615         CLKDEV_ICK_ID("icka", "sh_fsi2",        &div6_reparent_clks[DIV6_FSIA]),
616         CLKDEV_ICK_ID("ickb", "sh_fsi2",        &div6_reparent_clks[DIV6_FSIB]),
617         CLKDEV_ICK_ID("diva", "sh_fsi2",        &fsidivs[FSIDIV_A]),
618         CLKDEV_ICK_ID("divb", "sh_fsi2",        &fsidivs[FSIDIV_B]),
619         CLKDEV_ICK_ID("xcka", "sh_fsi2",        &fsiack_clk),
620         CLKDEV_ICK_ID("xckb", "sh_fsi2",        &fsibck_clk),
621 };
622 
623 void __init r8a7740_clock_init(u8 md_ck)
624 {
625         int k, ret = 0;
626 
627         /* detect system clock parent */
628         if (md_ck & MD_CK1)
629                 system_clk.parent = &extal1_div2_clk;
630         else
631                 system_clk.parent = &extal1_clk;
632 
633         /* detect RCLK parent */
634         switch (md_ck & (MD_CK2 | MD_CK1)) {
635         case MD_CK2 | MD_CK1:
636                 r_clk.parent = &extal1_div2048_clk;
637                 break;
638         case MD_CK2:
639                 r_clk.parent = &extal1_div1024_clk;
640                 break;
641         case MD_CK1:
642         default:
643                 r_clk.parent = &extalr_clk;
644                 break;
645         }
646 
647         for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
648                 ret = clk_register(main_clks[k]);
649 
650         if (!ret)
651                 ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
652 
653         if (!ret)
654                 ret = sh_clk_div6_register(div6_clks, DIV6_NR);
655 
656         if (!ret)
657                 ret = sh_clk_div6_reparent_register(div6_reparent_clks,
658                                                     DIV6_REPARENT_NR);
659 
660         if (!ret)
661                 ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
662 
663         for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
664                 ret = clk_register(late_main_clks[k]);
665 
666         if (!ret)
667                 ret = sh_clk_fsidiv_register(fsidivs, FSIDIV_REPARENT_NR);
668 
669         clkdev_add_table(lookups, ARRAY_SIZE(lookups));
670 
671         if (!ret)
672                 shmobile_clk_init();
673         else
674                 panic("failed to setup r8a7740 clocks\n");
675 }
676 

~ [ 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