Merge tag 'samsung-dt-2' of git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux...
[cascardo/linux.git] / arch / arm / mach-shmobile / clock-r8a7778.c
1 /*
2  * r8a7778 clock framework support
3  *
4  * Copyright (C) 2013  Renesas Solutions Corp.
5  * Copyright (C) 2013  Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6  *
7  * based on r8a7779
8  *
9  * Copyright (C) 2011  Renesas Solutions Corp.
10  * Copyright (C) 2011  Magnus Damm
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24  */
25
26 /*
27  *     MD      MD      MD      MD       PLLA   PLLB    EXTAL   clki    clkz
28  *     19      18      12      11                      (HMz)   (MHz)   (MHz)
29  *----------------------------------------------------------------------------
30  *     1       0       0       0       x21     x21     38.00   800     800
31  *     1       0       0       1       x24     x24     33.33   800     800
32  *     1       0       1       0       x28     x28     28.50   800     800
33  *     1       0       1       1       x32     x32     25.00   800     800
34  *     1       1       0       1       x24     x21     33.33   800     700
35  *     1       1       1       0       x28     x21     28.50   800     600
36  *     1       1       1       1       x32     x24     25.00   800     600
37  */
38
39 #include <linux/io.h>
40 #include <linux/sh_clk.h>
41 #include <linux/clkdev.h>
42 #include <mach/clock.h>
43 #include <mach/common.h>
44
45 #define MSTPCR0         IOMEM(0xffc80030)
46 #define MSTPCR1         IOMEM(0xffc80034)
47 #define MSTPCR3         IOMEM(0xffc8003c)
48 #define MSTPSR1         IOMEM(0xffc80044)
49 #define MSTPSR4         IOMEM(0xffc80048)
50 #define MSTPSR6         IOMEM(0xffc8004c)
51 #define MSTPCR4         IOMEM(0xffc80050)
52 #define MSTPCR5         IOMEM(0xffc80054)
53 #define MSTPCR6         IOMEM(0xffc80058)
54 #define MODEMR          0xFFCC0020
55
56 #define MD(nr)  BIT(nr)
57
58 /* ioremap() through clock mapping mandatory to avoid
59  * collision with ARM coherent DMA virtual memory range.
60  */
61
62 static struct clk_mapping cpg_mapping = {
63         .phys   = 0xffc80000,
64         .len    = 0x80,
65 };
66
67 static struct clk extal_clk = {
68         /* .rate will be updated on r8a7778_clock_init() */
69         .mapping = &cpg_mapping,
70 };
71
72 static struct clk audio_clk_a = {
73 };
74
75 static struct clk audio_clk_b = {
76 };
77
78 static struct clk audio_clk_c = {
79 };
80
81 /*
82  * clock ratio of these clock will be updated
83  * on r8a7778_clock_init()
84  */
85 SH_FIXED_RATIO_CLK_SET(plla_clk,        extal_clk, 1, 1);
86 SH_FIXED_RATIO_CLK_SET(pllb_clk,        extal_clk, 1, 1);
87 SH_FIXED_RATIO_CLK_SET(i_clk,           plla_clk,  1, 1);
88 SH_FIXED_RATIO_CLK_SET(s_clk,           plla_clk,  1, 1);
89 SH_FIXED_RATIO_CLK_SET(s1_clk,          plla_clk,  1, 1);
90 SH_FIXED_RATIO_CLK_SET(s3_clk,          plla_clk,  1, 1);
91 SH_FIXED_RATIO_CLK_SET(s4_clk,          plla_clk,  1, 1);
92 SH_FIXED_RATIO_CLK_SET(b_clk,           plla_clk,  1, 1);
93 SH_FIXED_RATIO_CLK_SET(out_clk,         plla_clk,  1, 1);
94 SH_FIXED_RATIO_CLK_SET(p_clk,           plla_clk,  1, 1);
95 SH_FIXED_RATIO_CLK_SET(g_clk,           plla_clk,  1, 1);
96 SH_FIXED_RATIO_CLK_SET(z_clk,           pllb_clk,  1, 1);
97
98 static struct clk *main_clks[] = {
99         &extal_clk,
100         &plla_clk,
101         &pllb_clk,
102         &i_clk,
103         &s_clk,
104         &s1_clk,
105         &s3_clk,
106         &s4_clk,
107         &b_clk,
108         &out_clk,
109         &p_clk,
110         &g_clk,
111         &z_clk,
112         &audio_clk_a,
113         &audio_clk_b,
114         &audio_clk_c,
115 };
116
117 enum {
118         MSTP531, MSTP530,
119         MSTP529, MSTP528, MSTP527, MSTP526, MSTP525, MSTP524, MSTP523,
120         MSTP331,
121         MSTP323, MSTP322, MSTP321,
122         MSTP311, MSTP310,
123         MSTP309, MSTP308, MSTP307,
124         MSTP114,
125         MSTP110, MSTP109,
126         MSTP100,
127         MSTP030,
128         MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021,
129         MSTP016, MSTP015, MSTP012, MSTP011, MSTP010,
130         MSTP009, MSTP008, MSTP007,
131         MSTP_NR };
132
133 static struct clk mstp_clks[MSTP_NR] = {
134         [MSTP531] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 31, 0), /* SCU0 */
135         [MSTP530] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 30, 0), /* SCU1 */
136         [MSTP529] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 29, 0), /* SCU2 */
137         [MSTP528] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 28, 0), /* SCU3 */
138         [MSTP527] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 27, 0), /* SCU4 */
139         [MSTP526] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 26, 0), /* SCU5 */
140         [MSTP525] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 25, 0), /* SCU6 */
141         [MSTP524] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 24, 0), /* SCU7 */
142         [MSTP523] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 23, 0), /* SCU8 */
143         [MSTP331] = SH_CLK_MSTP32(&s4_clk, MSTPCR3, 31, 0), /* MMC */
144         [MSTP323] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 23, 0), /* SDHI0 */
145         [MSTP322] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 22, 0), /* SDHI1 */
146         [MSTP321] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 21, 0), /* SDHI2 */
147         [MSTP311] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 11, 0), /* SSI4 */
148         [MSTP310] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 10, 0), /* SSI5 */
149         [MSTP309] = SH_CLK_MSTP32(&p_clk, MSTPCR3,  9, 0), /* SSI6 */
150         [MSTP308] = SH_CLK_MSTP32(&p_clk, MSTPCR3,  8, 0), /* SSI7 */
151         [MSTP307] = SH_CLK_MSTP32(&p_clk, MSTPCR3,  7, 0), /* SSI8 */
152         [MSTP114] = SH_CLK_MSTP32(&p_clk, MSTPCR1, 14, 0), /* Ether */
153         [MSTP110] = SH_CLK_MSTP32(&s_clk, MSTPCR1, 10, 0), /* VIN0 */
154         [MSTP109] = SH_CLK_MSTP32(&s_clk, MSTPCR1,  9, 0), /* VIN1 */
155         [MSTP100] = SH_CLK_MSTP32(&p_clk, MSTPCR1,  0, 0), /* USB0/1 */
156         [MSTP030] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 30, 0), /* I2C0 */
157         [MSTP029] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 29, 0), /* I2C1 */
158         [MSTP028] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 28, 0), /* I2C2 */
159         [MSTP027] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 27, 0), /* I2C3 */
160         [MSTP026] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 26, 0), /* SCIF0 */
161         [MSTP025] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 25, 0), /* SCIF1 */
162         [MSTP024] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 24, 0), /* SCIF2 */
163         [MSTP023] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 23, 0), /* SCIF3 */
164         [MSTP022] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 22, 0), /* SCIF4 */
165         [MSTP021] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 21, 0), /* SCIF5 */
166         [MSTP016] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 16, 0), /* TMU0 */
167         [MSTP015] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 15, 0), /* TMU1 */
168         [MSTP012] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 12, 0), /* SSI0 */
169         [MSTP011] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 11, 0), /* SSI1 */
170         [MSTP010] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 10, 0), /* SSI2 */
171         [MSTP009] = SH_CLK_MSTP32(&p_clk, MSTPCR0,  9, 0), /* SSI3 */
172         [MSTP008] = SH_CLK_MSTP32(&p_clk, MSTPCR0,  8, 0), /* SRU */
173         [MSTP007] = SH_CLK_MSTP32(&s_clk, MSTPCR0,  7, 0), /* HSPI */
174 };
175
176 static struct clk_lookup lookups[] = {
177         /* main */
178         CLKDEV_CON_ID("shyway_clk",     &s_clk),
179         CLKDEV_CON_ID("peripheral_clk", &p_clk),
180
181         /* MSTP32 clocks */
182         CLKDEV_DEV_ID("sh_mmcif", &mstp_clks[MSTP331]), /* MMC */
183         CLKDEV_DEV_ID("ffe4e000.mmc", &mstp_clks[MSTP331]), /* MMC */
184         CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP323]), /* SDHI0 */
185         CLKDEV_DEV_ID("ffe4c000.sd", &mstp_clks[MSTP323]), /* SDHI0 */
186         CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */
187         CLKDEV_DEV_ID("ffe4d000.sd", &mstp_clks[MSTP322]), /* SDHI1 */
188         CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */
189         CLKDEV_DEV_ID("ffe4f000.sd", &mstp_clks[MSTP321]), /* SDHI2 */
190         CLKDEV_DEV_ID("r8a777x-ether", &mstp_clks[MSTP114]), /* Ether */
191         CLKDEV_DEV_ID("r8a7778-vin.0", &mstp_clks[MSTP110]), /* VIN0 */
192         CLKDEV_DEV_ID("r8a7778-vin.1", &mstp_clks[MSTP109]), /* VIN1 */
193         CLKDEV_DEV_ID("ehci-platform", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */
194         CLKDEV_DEV_ID("ohci-platform", &mstp_clks[MSTP100]), /* USB OHCI port0/1 */
195         CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP100]), /* USB FUNC */
196         CLKDEV_DEV_ID("i2c-rcar.0", &mstp_clks[MSTP030]), /* I2C0 */
197         CLKDEV_DEV_ID("ffc70000.i2c", &mstp_clks[MSTP030]), /* I2C0 */
198         CLKDEV_DEV_ID("i2c-rcar.1", &mstp_clks[MSTP029]), /* I2C1 */
199         CLKDEV_DEV_ID("ffc71000.i2c", &mstp_clks[MSTP029]), /* I2C1 */
200         CLKDEV_DEV_ID("i2c-rcar.2", &mstp_clks[MSTP028]), /* I2C2 */
201         CLKDEV_DEV_ID("ffc72000.i2c", &mstp_clks[MSTP028]), /* I2C2 */
202         CLKDEV_DEV_ID("i2c-rcar.3", &mstp_clks[MSTP027]), /* I2C3 */
203         CLKDEV_DEV_ID("ffc73000.i2c", &mstp_clks[MSTP027]), /* I2C3 */
204         CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP026]), /* SCIF0 */
205         CLKDEV_DEV_ID("ffe40000.serial", &mstp_clks[MSTP026]), /* SCIF0 */
206         CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP025]), /* SCIF1 */
207         CLKDEV_DEV_ID("ffe41000.serial", &mstp_clks[MSTP025]), /* SCIF1 */
208         CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP024]), /* SCIF2 */
209         CLKDEV_DEV_ID("ffe42000.serial", &mstp_clks[MSTP024]), /* SCIF2 */
210         CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP023]), /* SCIF3 */
211         CLKDEV_DEV_ID("ffe43000.serial", &mstp_clks[MSTP023]), /* SCIF3 */
212         CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP022]), /* SCIF4 */
213         CLKDEV_DEV_ID("ffe44000.serial", &mstp_clks[MSTP022]), /* SCIF4 */
214         CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP021]), /* SCIF6 */
215         CLKDEV_DEV_ID("ffe45000.serial", &mstp_clks[MSTP021]), /* SCIF5 */
216         CLKDEV_DEV_ID("sh-hspi.0", &mstp_clks[MSTP007]), /* HSPI0 */
217         CLKDEV_DEV_ID("fffc7000.spi", &mstp_clks[MSTP007]), /* HSPI0 */
218         CLKDEV_DEV_ID("sh-hspi.1", &mstp_clks[MSTP007]), /* HSPI1 */
219         CLKDEV_DEV_ID("fffc8000.spi", &mstp_clks[MSTP007]), /* HSPI1 */
220         CLKDEV_DEV_ID("sh-hspi.2", &mstp_clks[MSTP007]), /* HSPI2 */
221         CLKDEV_DEV_ID("fffc6000.spi", &mstp_clks[MSTP007]), /* HSPI2 */
222         CLKDEV_DEV_ID("rcar_sound", &mstp_clks[MSTP008]), /* SRU */
223
224         CLKDEV_ICK_ID("clk_a", "rcar_sound", &audio_clk_a),
225         CLKDEV_ICK_ID("clk_b", "rcar_sound", &audio_clk_b),
226         CLKDEV_ICK_ID("clk_c", "rcar_sound", &audio_clk_c),
227         CLKDEV_ICK_ID("clk_i", "rcar_sound", &s1_clk),
228         CLKDEV_ICK_ID("ssi.0", "rcar_sound", &mstp_clks[MSTP012]),
229         CLKDEV_ICK_ID("ssi.1", "rcar_sound", &mstp_clks[MSTP011]),
230         CLKDEV_ICK_ID("ssi.2", "rcar_sound", &mstp_clks[MSTP010]),
231         CLKDEV_ICK_ID("ssi.3", "rcar_sound", &mstp_clks[MSTP009]),
232         CLKDEV_ICK_ID("ssi.4", "rcar_sound", &mstp_clks[MSTP311]),
233         CLKDEV_ICK_ID("ssi.5", "rcar_sound", &mstp_clks[MSTP310]),
234         CLKDEV_ICK_ID("ssi.6", "rcar_sound", &mstp_clks[MSTP309]),
235         CLKDEV_ICK_ID("ssi.7", "rcar_sound", &mstp_clks[MSTP308]),
236         CLKDEV_ICK_ID("ssi.8", "rcar_sound", &mstp_clks[MSTP307]),
237         CLKDEV_ICK_ID("src.0", "rcar_sound", &mstp_clks[MSTP531]),
238         CLKDEV_ICK_ID("src.1", "rcar_sound", &mstp_clks[MSTP530]),
239         CLKDEV_ICK_ID("src.2", "rcar_sound", &mstp_clks[MSTP529]),
240         CLKDEV_ICK_ID("src.3", "rcar_sound", &mstp_clks[MSTP528]),
241         CLKDEV_ICK_ID("src.4", "rcar_sound", &mstp_clks[MSTP527]),
242         CLKDEV_ICK_ID("src.5", "rcar_sound", &mstp_clks[MSTP526]),
243         CLKDEV_ICK_ID("src.6", "rcar_sound", &mstp_clks[MSTP525]),
244         CLKDEV_ICK_ID("src.7", "rcar_sound", &mstp_clks[MSTP524]),
245         CLKDEV_ICK_ID("src.8", "rcar_sound", &mstp_clks[MSTP523]),
246         CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[MSTP016]),
247         CLKDEV_ICK_ID("fck", "ffd80000.timer", &mstp_clks[MSTP016]),
248         CLKDEV_ICK_ID("fck", "sh-tmu.1", &mstp_clks[MSTP015]),
249         CLKDEV_ICK_ID("fck", "ffd81000.timer", &mstp_clks[MSTP015]),
250 };
251
252 void __init r8a7778_clock_init(void)
253 {
254         void __iomem *modemr = ioremap_nocache(MODEMR, PAGE_SIZE);
255         u32 mode;
256         int k, ret = 0;
257
258         BUG_ON(!modemr);
259         mode = ioread32(modemr);
260         iounmap(modemr);
261
262         switch (mode & (MD(19) | MD(18) | MD(12) | MD(11))) {
263         case MD(19):
264                 extal_clk.rate = 38000000;
265                 SH_CLK_SET_RATIO(&plla_clk_ratio,       21, 1);
266                 SH_CLK_SET_RATIO(&pllb_clk_ratio,       21, 1);
267                 break;
268         case MD(19) | MD(11):
269                 extal_clk.rate = 33333333;
270                 SH_CLK_SET_RATIO(&plla_clk_ratio,       24, 1);
271                 SH_CLK_SET_RATIO(&pllb_clk_ratio,       24, 1);
272                 break;
273         case MD(19) | MD(12):
274                 extal_clk.rate = 28500000;
275                 SH_CLK_SET_RATIO(&plla_clk_ratio,       28, 1);
276                 SH_CLK_SET_RATIO(&pllb_clk_ratio,       28, 1);
277                 break;
278         case MD(19) | MD(12) | MD(11):
279                 extal_clk.rate = 25000000;
280                 SH_CLK_SET_RATIO(&plla_clk_ratio,       32, 1);
281                 SH_CLK_SET_RATIO(&pllb_clk_ratio,       32, 1);
282                 break;
283         case MD(19) | MD(18) | MD(11):
284                 extal_clk.rate = 33333333;
285                 SH_CLK_SET_RATIO(&plla_clk_ratio,       24, 1);
286                 SH_CLK_SET_RATIO(&pllb_clk_ratio,       21, 1);
287                 break;
288         case MD(19) | MD(18) | MD(12):
289                 extal_clk.rate = 28500000;
290                 SH_CLK_SET_RATIO(&plla_clk_ratio,       28, 1);
291                 SH_CLK_SET_RATIO(&pllb_clk_ratio,       21, 1);
292                 break;
293         case MD(19) | MD(18) | MD(12) | MD(11):
294                 extal_clk.rate = 25000000;
295                 SH_CLK_SET_RATIO(&plla_clk_ratio,       32, 1);
296                 SH_CLK_SET_RATIO(&pllb_clk_ratio,       24, 1);
297                 break;
298         default:
299                 BUG();
300         }
301
302         if (mode & MD(1)) {
303                 SH_CLK_SET_RATIO(&i_clk_ratio,  1, 1);
304                 SH_CLK_SET_RATIO(&s_clk_ratio,  1, 3);
305                 SH_CLK_SET_RATIO(&s1_clk_ratio, 1, 6);
306                 SH_CLK_SET_RATIO(&s3_clk_ratio, 1, 4);
307                 SH_CLK_SET_RATIO(&s4_clk_ratio, 1, 8);
308                 SH_CLK_SET_RATIO(&p_clk_ratio,  1, 12);
309                 SH_CLK_SET_RATIO(&g_clk_ratio,  1, 12);
310                 if (mode & MD(2)) {
311                         SH_CLK_SET_RATIO(&b_clk_ratio,          1, 18);
312                         SH_CLK_SET_RATIO(&out_clk_ratio,        1, 18);
313                 } else {
314                         SH_CLK_SET_RATIO(&b_clk_ratio,          1, 12);
315                         SH_CLK_SET_RATIO(&out_clk_ratio,        1, 12);
316                 }
317         } else {
318                 SH_CLK_SET_RATIO(&i_clk_ratio,  1, 1);
319                 SH_CLK_SET_RATIO(&s_clk_ratio,  1, 4);
320                 SH_CLK_SET_RATIO(&s1_clk_ratio, 1, 8);
321                 SH_CLK_SET_RATIO(&s3_clk_ratio, 1, 4);
322                 SH_CLK_SET_RATIO(&s4_clk_ratio, 1, 8);
323                 SH_CLK_SET_RATIO(&p_clk_ratio,  1, 16);
324                 SH_CLK_SET_RATIO(&g_clk_ratio,  1, 12);
325                 if (mode & MD(2)) {
326                         SH_CLK_SET_RATIO(&b_clk_ratio,          1, 16);
327                         SH_CLK_SET_RATIO(&out_clk_ratio,        1, 16);
328                 } else {
329                         SH_CLK_SET_RATIO(&b_clk_ratio,          1, 12);
330                         SH_CLK_SET_RATIO(&out_clk_ratio,        1, 12);
331                 }
332         }
333
334         for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
335                 ret = clk_register(main_clks[k]);
336
337         if (!ret)
338                 ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
339
340         clkdev_add_table(lookups, ARRAY_SIZE(lookups));
341
342         if (!ret)
343                 shmobile_clk_init();
344         else
345                 panic("failed to setup r8a7778 clocks\n");
346 }