Merge tag 'locks-v3.16-2' of git://git.samba.org/jlayton/linux
[linux/fpc-iii.git] / arch / arm / mach-shmobile / clock-r8a7778.c
blob13f8f3ab884021d30dbaa10b1daab4200aefe5e1
1 /*
2 * r8a7778 clock framework support
4 * Copyright (C) 2013 Renesas Solutions Corp.
5 * Copyright (C) 2013 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
7 * based on r8a7779
9 * Copyright (C) 2011 Renesas Solutions Corp.
10 * Copyright (C) 2011 Magnus Damm
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
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.
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
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
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>
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
56 #define MD(nr) BIT(nr)
58 /* ioremap() through clock mapping mandatory to avoid
59 * collision with ARM coherent DMA virtual memory range.
62 static struct clk_mapping cpg_mapping = {
63 .phys = 0xffc80000,
64 .len = 0x80,
67 static struct clk extal_clk = {
68 /* .rate will be updated on r8a7778_clock_init() */
69 .mapping = &cpg_mapping,
72 static struct clk audio_clk_a = {
75 static struct clk audio_clk_b = {
78 static struct clk audio_clk_c = {
82 * clock ratio of these clock will be updated
83 * on r8a7778_clock_init()
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);
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,
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 };
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 */
176 static struct clk_lookup lookups[] = {
177 /* main */
178 CLKDEV_CON_ID("shyway_clk", &s_clk),
179 CLKDEV_CON_ID("peripheral_clk", &p_clk),
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("sh-sci.1", &mstp_clks[MSTP025]), /* SCIF1 */
206 CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP024]), /* SCIF2 */
207 CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP023]), /* SCIF3 */
208 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP022]), /* SCIF4 */
209 CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP021]), /* SCIF6 */
210 CLKDEV_DEV_ID("sh-hspi.0", &mstp_clks[MSTP007]), /* HSPI0 */
211 CLKDEV_DEV_ID("fffc7000.spi", &mstp_clks[MSTP007]), /* HSPI0 */
212 CLKDEV_DEV_ID("sh-hspi.1", &mstp_clks[MSTP007]), /* HSPI1 */
213 CLKDEV_DEV_ID("fffc8000.spi", &mstp_clks[MSTP007]), /* HSPI1 */
214 CLKDEV_DEV_ID("sh-hspi.2", &mstp_clks[MSTP007]), /* HSPI2 */
215 CLKDEV_DEV_ID("fffc6000.spi", &mstp_clks[MSTP007]), /* HSPI2 */
216 CLKDEV_DEV_ID("rcar_sound", &mstp_clks[MSTP008]), /* SRU */
218 CLKDEV_ICK_ID("clk_a", "rcar_sound", &audio_clk_a),
219 CLKDEV_ICK_ID("clk_b", "rcar_sound", &audio_clk_b),
220 CLKDEV_ICK_ID("clk_c", "rcar_sound", &audio_clk_c),
221 CLKDEV_ICK_ID("clk_i", "rcar_sound", &s1_clk),
222 CLKDEV_ICK_ID("ssi.0", "rcar_sound", &mstp_clks[MSTP012]),
223 CLKDEV_ICK_ID("ssi.1", "rcar_sound", &mstp_clks[MSTP011]),
224 CLKDEV_ICK_ID("ssi.2", "rcar_sound", &mstp_clks[MSTP010]),
225 CLKDEV_ICK_ID("ssi.3", "rcar_sound", &mstp_clks[MSTP009]),
226 CLKDEV_ICK_ID("ssi.4", "rcar_sound", &mstp_clks[MSTP311]),
227 CLKDEV_ICK_ID("ssi.5", "rcar_sound", &mstp_clks[MSTP310]),
228 CLKDEV_ICK_ID("ssi.6", "rcar_sound", &mstp_clks[MSTP309]),
229 CLKDEV_ICK_ID("ssi.7", "rcar_sound", &mstp_clks[MSTP308]),
230 CLKDEV_ICK_ID("ssi.8", "rcar_sound", &mstp_clks[MSTP307]),
231 CLKDEV_ICK_ID("src.0", "rcar_sound", &mstp_clks[MSTP531]),
232 CLKDEV_ICK_ID("src.1", "rcar_sound", &mstp_clks[MSTP530]),
233 CLKDEV_ICK_ID("src.2", "rcar_sound", &mstp_clks[MSTP529]),
234 CLKDEV_ICK_ID("src.3", "rcar_sound", &mstp_clks[MSTP528]),
235 CLKDEV_ICK_ID("src.4", "rcar_sound", &mstp_clks[MSTP527]),
236 CLKDEV_ICK_ID("src.5", "rcar_sound", &mstp_clks[MSTP526]),
237 CLKDEV_ICK_ID("src.6", "rcar_sound", &mstp_clks[MSTP525]),
238 CLKDEV_ICK_ID("src.7", "rcar_sound", &mstp_clks[MSTP524]),
239 CLKDEV_ICK_ID("src.8", "rcar_sound", &mstp_clks[MSTP523]),
240 CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[MSTP016]),
241 CLKDEV_ICK_ID("fck", "sh-tmu.1", &mstp_clks[MSTP015]),
244 void __init r8a7778_clock_init(void)
246 void __iomem *modemr = ioremap_nocache(MODEMR, PAGE_SIZE);
247 u32 mode;
248 int k, ret = 0;
250 BUG_ON(!modemr);
251 mode = ioread32(modemr);
252 iounmap(modemr);
254 switch (mode & (MD(19) | MD(18) | MD(12) | MD(11))) {
255 case MD(19):
256 extal_clk.rate = 38000000;
257 SH_CLK_SET_RATIO(&plla_clk_ratio, 21, 1);
258 SH_CLK_SET_RATIO(&pllb_clk_ratio, 21, 1);
259 break;
260 case MD(19) | MD(11):
261 extal_clk.rate = 33333333;
262 SH_CLK_SET_RATIO(&plla_clk_ratio, 24, 1);
263 SH_CLK_SET_RATIO(&pllb_clk_ratio, 24, 1);
264 break;
265 case MD(19) | MD(12):
266 extal_clk.rate = 28500000;
267 SH_CLK_SET_RATIO(&plla_clk_ratio, 28, 1);
268 SH_CLK_SET_RATIO(&pllb_clk_ratio, 28, 1);
269 break;
270 case MD(19) | MD(12) | MD(11):
271 extal_clk.rate = 25000000;
272 SH_CLK_SET_RATIO(&plla_clk_ratio, 32, 1);
273 SH_CLK_SET_RATIO(&pllb_clk_ratio, 32, 1);
274 break;
275 case MD(19) | MD(18) | MD(11):
276 extal_clk.rate = 33333333;
277 SH_CLK_SET_RATIO(&plla_clk_ratio, 24, 1);
278 SH_CLK_SET_RATIO(&pllb_clk_ratio, 21, 1);
279 break;
280 case MD(19) | MD(18) | MD(12):
281 extal_clk.rate = 28500000;
282 SH_CLK_SET_RATIO(&plla_clk_ratio, 28, 1);
283 SH_CLK_SET_RATIO(&pllb_clk_ratio, 21, 1);
284 break;
285 case MD(19) | MD(18) | MD(12) | MD(11):
286 extal_clk.rate = 25000000;
287 SH_CLK_SET_RATIO(&plla_clk_ratio, 32, 1);
288 SH_CLK_SET_RATIO(&pllb_clk_ratio, 24, 1);
289 break;
290 default:
291 BUG();
294 if (mode & MD(1)) {
295 SH_CLK_SET_RATIO(&i_clk_ratio, 1, 1);
296 SH_CLK_SET_RATIO(&s_clk_ratio, 1, 3);
297 SH_CLK_SET_RATIO(&s1_clk_ratio, 1, 6);
298 SH_CLK_SET_RATIO(&s3_clk_ratio, 1, 4);
299 SH_CLK_SET_RATIO(&s4_clk_ratio, 1, 8);
300 SH_CLK_SET_RATIO(&p_clk_ratio, 1, 12);
301 SH_CLK_SET_RATIO(&g_clk_ratio, 1, 12);
302 if (mode & MD(2)) {
303 SH_CLK_SET_RATIO(&b_clk_ratio, 1, 18);
304 SH_CLK_SET_RATIO(&out_clk_ratio, 1, 18);
305 } else {
306 SH_CLK_SET_RATIO(&b_clk_ratio, 1, 12);
307 SH_CLK_SET_RATIO(&out_clk_ratio, 1, 12);
309 } else {
310 SH_CLK_SET_RATIO(&i_clk_ratio, 1, 1);
311 SH_CLK_SET_RATIO(&s_clk_ratio, 1, 4);
312 SH_CLK_SET_RATIO(&s1_clk_ratio, 1, 8);
313 SH_CLK_SET_RATIO(&s3_clk_ratio, 1, 4);
314 SH_CLK_SET_RATIO(&s4_clk_ratio, 1, 8);
315 SH_CLK_SET_RATIO(&p_clk_ratio, 1, 16);
316 SH_CLK_SET_RATIO(&g_clk_ratio, 1, 12);
317 if (mode & MD(2)) {
318 SH_CLK_SET_RATIO(&b_clk_ratio, 1, 16);
319 SH_CLK_SET_RATIO(&out_clk_ratio, 1, 16);
320 } else {
321 SH_CLK_SET_RATIO(&b_clk_ratio, 1, 12);
322 SH_CLK_SET_RATIO(&out_clk_ratio, 1, 12);
326 for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
327 ret = clk_register(main_clks[k]);
329 if (!ret)
330 ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
332 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
334 if (!ret)
335 shmobile_clk_init();
336 else
337 panic("failed to setup r8a7778 clocks\n");