Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf
[deliverable/linux.git] / arch / arm / mach-shmobile / clock-r8a7790.c
CommitLineData
0468b2d6
MD
1/*
2 * r8a7790 clock framework support
3 *
4 * Copyright (C) 2013 Renesas Solutions Corp.
5 * Copyright (C) 2013 Magnus Damm
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; 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 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20#include <linux/init.h>
21#include <linux/io.h>
22#include <linux/kernel.h>
23#include <linux/sh_clk.h>
24#include <linux/clkdev.h>
8d100c04 25#include <mach/clock.h>
0468b2d6 26#include <mach/common.h>
512e53bc 27#include <mach/r8a7790.h>
0468b2d6 28
8d100c04
KM
29/*
30 * MD EXTAL PLL0 PLL1 PLL3
31 * 14 13 19 (MHz) *1 *1
32 *---------------------------------------------------
33 * 0 0 0 15 x 1 x172/2 x208/2 x106
34 * 0 0 1 15 x 1 x172/2 x208/2 x88
35 * 0 1 0 20 x 1 x130/2 x156/2 x80
36 * 0 1 1 20 x 1 x130/2 x156/2 x66
37 * 1 0 0 26 / 2 x200/2 x240/2 x122
38 * 1 0 1 26 / 2 x200/2 x240/2 x102
39 * 1 1 0 30 / 2 x172/2 x208/2 x106
40 * 1 1 1 30 / 2 x172/2 x208/2 x88
41 *
42 * *1 : Table 7.6 indicates VCO ouput (PLLx = VCO/2)
43 * see "p1 / 2" on R8A7790_CLOCK_ROOT() below
44 */
45
0468b2d6
MD
46#define CPG_BASE 0xe6150000
47#define CPG_LEN 0x1000
48
99ade1a0 49#define SMSTPCR1 0xe6150134
55d9fab2 50#define SMSTPCR2 0xe6150138
aa9c185b 51#define SMSTPCR3 0xe615013c
a4b91be0 52#define SMSTPCR5 0xe6150144
55d9fab2 53#define SMSTPCR7 0xe615014c
9b0b9c01 54#define SMSTPCR8 0xe6150990
911a644c 55#define SMSTPCR9 0xe6150994
55d9fab2 56
9f13ee6f 57#define SDCKCR 0xE6150074
46632512
KM
58#define SD2CKCR 0xE6150078
59#define SD3CKCR 0xE615007C
60#define MMC0CKCR 0xE6150240
61#define MMC1CKCR 0xE6150244
62#define SSPCKCR 0xE6150248
63#define SSPRSCKCR 0xE615024C
8d100c04 64
0468b2d6
MD
65static struct clk_mapping cpg_mapping = {
66 .phys = CPG_BASE,
67 .len = CPG_LEN,
68};
69
8d100c04
KM
70static struct clk extal_clk = {
71 /* .rate will be updated on r8a7790_clock_init() */
55d9fab2
MD
72 .mapping = &cpg_mapping,
73};
74
8d100c04
KM
75static struct sh_clk_ops followparent_clk_ops = {
76 .recalc = followparent_recalc,
55d9fab2
MD
77};
78
8d100c04
KM
79static struct clk main_clk = {
80 /* .parent will be set r8a73a4_clock_init */
81 .ops = &followparent_clk_ops,
82};
83
84/*
85 * clock ratio of these clock will be updated
86 * on r8a7790_clock_init()
87 */
88SH_FIXED_RATIO_CLK_SET(pll1_clk, main_clk, 1, 1);
89SH_FIXED_RATIO_CLK_SET(pll3_clk, main_clk, 1, 1);
90SH_FIXED_RATIO_CLK_SET(lb_clk, pll1_clk, 1, 1);
91SH_FIXED_RATIO_CLK_SET(qspi_clk, pll1_clk, 1, 1);
92
93/* fixed ratio clock */
94SH_FIXED_RATIO_CLK_SET(extal_div2_clk, extal_clk, 1, 2);
95SH_FIXED_RATIO_CLK_SET(cp_clk, extal_clk, 1, 2);
96
97SH_FIXED_RATIO_CLK_SET(pll1_div2_clk, pll1_clk, 1, 2);
98SH_FIXED_RATIO_CLK_SET(zg_clk, pll1_clk, 1, 3);
99SH_FIXED_RATIO_CLK_SET(zx_clk, pll1_clk, 1, 3);
100SH_FIXED_RATIO_CLK_SET(zs_clk, pll1_clk, 1, 6);
101SH_FIXED_RATIO_CLK_SET(hp_clk, pll1_clk, 1, 12);
102SH_FIXED_RATIO_CLK_SET(i_clk, pll1_clk, 1, 2);
103SH_FIXED_RATIO_CLK_SET(b_clk, pll1_clk, 1, 12);
104SH_FIXED_RATIO_CLK_SET(p_clk, pll1_clk, 1, 24);
105SH_FIXED_RATIO_CLK_SET(cl_clk, pll1_clk, 1, 48);
106SH_FIXED_RATIO_CLK_SET(m2_clk, pll1_clk, 1, 8);
107SH_FIXED_RATIO_CLK_SET(imp_clk, pll1_clk, 1, 4);
108SH_FIXED_RATIO_CLK_SET(rclk_clk, pll1_clk, 1, (48 * 1024));
109SH_FIXED_RATIO_CLK_SET(oscclk_clk, pll1_clk, 1, (12 * 1024));
110
111SH_FIXED_RATIO_CLK_SET(zb3_clk, pll3_clk, 1, 4);
112SH_FIXED_RATIO_CLK_SET(zb3d2_clk, pll3_clk, 1, 8);
113SH_FIXED_RATIO_CLK_SET(ddr_clk, pll3_clk, 1, 8);
114SH_FIXED_RATIO_CLK_SET(mp_clk, pll1_div2_clk, 1, 15);
115
0468b2d6 116static struct clk *main_clks[] = {
8d100c04
KM
117 &extal_clk,
118 &extal_div2_clk,
119 &main_clk,
120 &pll1_clk,
121 &pll1_div2_clk,
122 &pll3_clk,
123 &lb_clk,
124 &qspi_clk,
125 &zg_clk,
126 &zx_clk,
127 &zs_clk,
128 &hp_clk,
129 &i_clk,
130 &b_clk,
55d9fab2 131 &p_clk,
8d100c04
KM
132 &cl_clk,
133 &m2_clk,
134 &imp_clk,
135 &rclk_clk,
136 &oscclk_clk,
137 &zb3_clk,
138 &zb3d2_clk,
139 &ddr_clk,
55d9fab2 140 &mp_clk,
8d100c04 141 &cp_clk,
0468b2d6
MD
142};
143
9f13ee6f
KM
144/* SDHI (DIV4) clock */
145static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18, 24, 0, 36, 48, 10 };
146
147static struct clk_div_mult_table div4_div_mult_table = {
148 .divisors = divisors,
149 .nr_divisors = ARRAY_SIZE(divisors),
150};
151
152static struct clk_div4_table div4_table = {
153 .div_mult_table = &div4_div_mult_table,
154};
155
156enum {
157 DIV4_SDH, DIV4_SD0, DIV4_SD1, DIV4_NR
158};
159
72378a4a 160static struct clk div4_clks[DIV4_NR] = {
9f13ee6f
KM
161 [DIV4_SDH] = SH_CLK_DIV4(&pll1_clk, SDCKCR, 8, 0x0dff, CLK_ENABLE_ON_INIT),
162 [DIV4_SD0] = SH_CLK_DIV4(&pll1_clk, SDCKCR, 4, 0x1de0, CLK_ENABLE_ON_INIT),
163 [DIV4_SD1] = SH_CLK_DIV4(&pll1_clk, SDCKCR, 0, 0x1de0, CLK_ENABLE_ON_INIT),
164};
165
46632512
KM
166/* DIV6 clocks */
167enum {
168 DIV6_SD2, DIV6_SD3,
169 DIV6_MMC0, DIV6_MMC1,
170 DIV6_SSP, DIV6_SSPRS,
171 DIV6_NR
172};
173
174static struct clk div6_clks[DIV6_NR] = {
175 [DIV6_SD2] = SH_CLK_DIV6(&pll1_div2_clk, SD2CKCR, 0),
176 [DIV6_SD3] = SH_CLK_DIV6(&pll1_div2_clk, SD3CKCR, 0),
177 [DIV6_MMC0] = SH_CLK_DIV6(&pll1_div2_clk, MMC0CKCR, 0),
178 [DIV6_MMC1] = SH_CLK_DIV6(&pll1_div2_clk, MMC1CKCR, 0),
179 [DIV6_SSP] = SH_CLK_DIV6(&pll1_div2_clk, SSPCKCR, 0),
180 [DIV6_SSPRS] = SH_CLK_DIV6(&pll1_div2_clk, SSPRSCKCR, 0),
181};
182
9f13ee6f 183/* MSTP */
aa9c185b 184enum {
911a644c 185 MSTP931, MSTP930, MSTP929, MSTP928,
9b0b9c01 186 MSTP813,
9d8907c4 187 MSTP726, MSTP725, MSTP724, MSTP723, MSTP722, MSTP721, MSTP720,
729cb826 188 MSTP717, MSTP716,
a4b91be0 189 MSTP522,
018222f5 190 MSTP315, MSTP314, MSTP313, MSTP312, MSTP311, MSTP305, MSTP304,
aa9c185b 191 MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202,
99ade1a0 192 MSTP124,
aa9c185b
LP
193 MSTP_NR
194};
195
0468b2d6 196static struct clk mstp_clks[MSTP_NR] = {
911a644c
GL
197 [MSTP931] = SH_CLK_MSTP32(&hp_clk, SMSTPCR9, 31, 0), /* I2C0 */
198 [MSTP930] = SH_CLK_MSTP32(&hp_clk, SMSTPCR9, 30, 0), /* I2C1 */
199 [MSTP929] = SH_CLK_MSTP32(&hp_clk, SMSTPCR9, 29, 0), /* I2C2 */
200 [MSTP928] = SH_CLK_MSTP32(&hp_clk, SMSTPCR9, 28, 0), /* I2C3 */
9b0b9c01 201 [MSTP813] = SH_CLK_MSTP32(&p_clk, SMSTPCR8, 13, 0), /* Ether */
9d8907c4
LP
202 [MSTP726] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 26, 0), /* LVDS0 */
203 [MSTP725] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 25, 0), /* LVDS1 */
204 [MSTP724] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 24, 0), /* DU0 */
205 [MSTP723] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 23, 0), /* DU1 */
206 [MSTP722] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 22, 0), /* DU2 */
55d9fab2
MD
207 [MSTP721] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 21, 0), /* SCIF0 */
208 [MSTP720] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 20, 0), /* SCIF1 */
29eb2ba8
MD
209 [MSTP717] = SH_CLK_MSTP32(&zs_clk, SMSTPCR7, 17, 0), /* HSCIF0 */
210 [MSTP716] = SH_CLK_MSTP32(&zs_clk, SMSTPCR7, 16, 0), /* HSCIF1 */
211 [MSTP522] = SH_CLK_MSTP32(&extal_clk, SMSTPCR5, 22, 0), /* Thermal */
018222f5
GL
212 [MSTP315] = SH_CLK_MSTP32(&div6_clks[DIV6_MMC0], SMSTPCR3, 15, 0), /* MMC0 */
213 [MSTP314] = SH_CLK_MSTP32(&div4_clks[DIV4_SD0], SMSTPCR3, 14, 0), /* SDHI0 */
214 [MSTP313] = SH_CLK_MSTP32(&div4_clks[DIV4_SD1], SMSTPCR3, 13, 0), /* SDHI1 */
215 [MSTP312] = SH_CLK_MSTP32(&div6_clks[DIV6_SD2], SMSTPCR3, 12, 0), /* SDHI2 */
216 [MSTP311] = SH_CLK_MSTP32(&div6_clks[DIV6_SD3], SMSTPCR3, 11, 0), /* SDHI3 */
217 [MSTP305] = SH_CLK_MSTP32(&div6_clks[DIV6_MMC1], SMSTPCR3, 5, 0), /* MMC1 */
aa9c185b 218 [MSTP304] = SH_CLK_MSTP32(&cp_clk, SMSTPCR3, 4, 0), /* TPU0 */
55d9fab2
MD
219 [MSTP216] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 16, 0), /* SCIFB2 */
220 [MSTP207] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 7, 0), /* SCIFB1 */
221 [MSTP206] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 6, 0), /* SCIFB0 */
222 [MSTP204] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 4, 0), /* SCIFA0 */
223 [MSTP203] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 3, 0), /* SCIFA1 */
224 [MSTP202] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 2, 0), /* SCIFA2 */
99ade1a0 225 [MSTP124] = SH_CLK_MSTP32(&rclk_clk, SMSTPCR1, 24, 0), /* CMT0 */
0468b2d6
MD
226};
227
228static struct clk_lookup lookups[] = {
8d100c04
KM
229
230 /* main clocks */
231 CLKDEV_CON_ID("extal", &extal_clk),
232 CLKDEV_CON_ID("extal_div2", &extal_div2_clk),
233 CLKDEV_CON_ID("main", &main_clk),
234 CLKDEV_CON_ID("pll1", &pll1_clk),
235 CLKDEV_CON_ID("pll1_div2", &pll1_div2_clk),
236 CLKDEV_CON_ID("pll3", &pll3_clk),
237 CLKDEV_CON_ID("zg", &zg_clk),
238 CLKDEV_CON_ID("zx", &zx_clk),
239 CLKDEV_CON_ID("zs", &zs_clk),
240 CLKDEV_CON_ID("hp", &hp_clk),
241 CLKDEV_CON_ID("i", &i_clk),
242 CLKDEV_CON_ID("b", &b_clk),
243 CLKDEV_CON_ID("lb", &lb_clk),
244 CLKDEV_CON_ID("p", &p_clk),
245 CLKDEV_CON_ID("cl", &cl_clk),
246 CLKDEV_CON_ID("m2", &m2_clk),
247 CLKDEV_CON_ID("imp", &imp_clk),
248 CLKDEV_CON_ID("rclk", &rclk_clk),
249 CLKDEV_CON_ID("oscclk", &oscclk_clk),
250 CLKDEV_CON_ID("zb3", &zb3_clk),
251 CLKDEV_CON_ID("zb3d2", &zb3d2_clk),
252 CLKDEV_CON_ID("ddr", &ddr_clk),
253 CLKDEV_CON_ID("mp", &mp_clk),
254 CLKDEV_CON_ID("qspi", &qspi_clk),
255 CLKDEV_CON_ID("cp", &cp_clk),
256
9f13ee6f
KM
257 /* DIV4 */
258 CLKDEV_CON_ID("sdh", &div4_clks[DIV4_SDH]),
9f13ee6f 259
46632512 260 /* DIV6 */
46632512
KM
261 CLKDEV_CON_ID("ssp", &div6_clks[DIV6_SSP]),
262 CLKDEV_CON_ID("ssprs", &div6_clks[DIV6_SSPRS]),
263
8d100c04 264 /* MSTP */
9d8907c4
LP
265 CLKDEV_ICK_ID("lvds.0", "rcar-du-r8a7790", &mstp_clks[MSTP726]),
266 CLKDEV_ICK_ID("lvds.1", "rcar-du-r8a7790", &mstp_clks[MSTP725]),
267 CLKDEV_ICK_ID("du.0", "rcar-du-r8a7790", &mstp_clks[MSTP724]),
268 CLKDEV_ICK_ID("du.1", "rcar-du-r8a7790", &mstp_clks[MSTP723]),
269 CLKDEV_ICK_ID("du.2", "rcar-du-r8a7790", &mstp_clks[MSTP722]),
55d9fab2
MD
270 CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]),
271 CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]),
272 CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP206]),
273 CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP207]),
274 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP216]),
275 CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP202]),
276 CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP721]),
277 CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP720]),
729cb826
UH
278 CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP717]),
279 CLKDEV_DEV_ID("sh-sci.9", &mstp_clks[MSTP716]),
911a644c
GL
280 CLKDEV_DEV_ID("e6508000.i2c", &mstp_clks[MSTP931]),
281 CLKDEV_DEV_ID("e6518000.i2c", &mstp_clks[MSTP930]),
282 CLKDEV_DEV_ID("e6530000.i2c", &mstp_clks[MSTP929]),
283 CLKDEV_DEV_ID("e6540000.i2c", &mstp_clks[MSTP928]),
9b0b9c01 284 CLKDEV_DEV_ID("r8a7790-ether", &mstp_clks[MSTP813]),
a4b91be0 285 CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]),
018222f5
GL
286 CLKDEV_DEV_ID("ee200000.mmcif", &mstp_clks[MSTP315]),
287 CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP315]),
288 CLKDEV_DEV_ID("ee100000.sdhi", &mstp_clks[MSTP314]),
289 CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]),
290 CLKDEV_DEV_ID("ee120000.sdhi", &mstp_clks[MSTP313]),
291 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]),
292 CLKDEV_DEV_ID("ee140000.sdhi", &mstp_clks[MSTP312]),
293 CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP312]),
294 CLKDEV_DEV_ID("ee160000.sdhi", &mstp_clks[MSTP311]),
295 CLKDEV_DEV_ID("sh_mobile_sdhi.3", &mstp_clks[MSTP311]),
296 CLKDEV_DEV_ID("ee220000.mmcif", &mstp_clks[MSTP305]),
297 CLKDEV_DEV_ID("sh_mmcif.1", &mstp_clks[MSTP305]),
99ade1a0 298 CLKDEV_DEV_ID("sh_cmt.0", &mstp_clks[MSTP124]),
0468b2d6
MD
299};
300
8d100c04
KM
301#define R8A7790_CLOCK_ROOT(e, m, p0, p1, p30, p31) \
302 extal_clk.rate = e * 1000 * 1000; \
303 main_clk.parent = m; \
304 SH_CLK_SET_RATIO(&pll1_clk_ratio, p1 / 2, 1); \
305 if (mode & MD(19)) \
306 SH_CLK_SET_RATIO(&pll3_clk_ratio, p31, 1); \
307 else \
308 SH_CLK_SET_RATIO(&pll3_clk_ratio, p30, 1)
309
310
0468b2d6
MD
311void __init r8a7790_clock_init(void)
312{
50c517d9 313 u32 mode = rcar_gen2_read_mode_pins();
0468b2d6
MD
314 int k, ret = 0;
315
8d100c04
KM
316 switch (mode & (MD(14) | MD(13))) {
317 case 0:
318 R8A7790_CLOCK_ROOT(15, &extal_clk, 172, 208, 106, 88);
319 break;
320 case MD(13):
321 R8A7790_CLOCK_ROOT(20, &extal_clk, 130, 156, 80, 66);
322 break;
323 case MD(14):
324 R8A7790_CLOCK_ROOT(26, &extal_div2_clk, 200, 240, 122, 102);
325 break;
326 case MD(13) | MD(14):
327 R8A7790_CLOCK_ROOT(30, &extal_div2_clk, 172, 208, 106, 88);
328 break;
329 }
330
331 if (mode & (MD(18)))
332 SH_CLK_SET_RATIO(&lb_clk_ratio, 1, 36);
333 else
334 SH_CLK_SET_RATIO(&lb_clk_ratio, 1, 24);
335
336 if ((mode & (MD(3) | MD(2) | MD(1))) == MD(2))
337 SH_CLK_SET_RATIO(&qspi_clk_ratio, 1, 16);
338 else
339 SH_CLK_SET_RATIO(&qspi_clk_ratio, 1, 20);
340
0468b2d6
MD
341 for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
342 ret = clk_register(main_clks[k]);
343
9f13ee6f
KM
344 if (!ret)
345 ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
346
46632512
KM
347 if (!ret)
348 ret = sh_clk_div6_register(div6_clks, DIV6_NR);
349
0468b2d6
MD
350 if (!ret)
351 ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
352
353 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
354
355 if (!ret)
356 shmobile_clk_init();
357 else
358 panic("failed to setup r8a7790 clocks\n");
359}
This page took 0.063702 seconds and 5 git commands to generate.