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