2 * r8a7791 clock framework support
4 * Copyright (C) 2013 Renesas Electronics Corporation
5 * Copyright (C) 2013 Renesas Solutions Corp.
6 * Copyright (C) 2013 Magnus Damm
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #include <linux/init.h>
23 #include <linux/kernel.h>
24 #include <linux/sh_clk.h>
25 #include <linux/clkdev.h>
26 #include <mach/clock.h>
27 #include <mach/common.h>
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
42 * *1 : Table 7.6 indicates VCO ouput (PLLx = VCO/2)
43 * see "p1 / 2" on R8A7791_CLOCK_ROOT() below
46 #define MD(nr) (1 << nr)
48 #define CPG_BASE 0xe6150000
49 #define CPG_LEN 0x1000
51 #define SMSTPCR0 0xE6150130
52 #define SMSTPCR1 0xE6150134
53 #define SMSTPCR2 0xe6150138
54 #define SMSTPCR3 0xE615013C
55 #define SMSTPCR5 0xE6150144
56 #define SMSTPCR7 0xe615014c
57 #define SMSTPCR8 0xE6150990
58 #define SMSTPCR9 0xE6150994
59 #define SMSTPCR10 0xE6150998
60 #define SMSTPCR11 0xE615099C
62 #define MSTPSR1 IOMEM(0xe6150038)
63 #define MSTPSR2 IOMEM(0xe6150040)
64 #define MSTPSR3 IOMEM(0xe6150048)
65 #define MSTPSR5 IOMEM(0xe615003c)
66 #define MSTPSR7 IOMEM(0xe61501c4)
67 #define MSTPSR8 IOMEM(0xe61509a0)
68 #define MSTPSR9 IOMEM(0xe61509a4)
69 #define MSTPSR11 IOMEM(0xe61509ac)
71 #define MODEMR 0xE6160060
72 #define SDCKCR 0xE6150074
73 #define SD1CKCR 0xE6150078
74 #define SD2CKCR 0xE615026c
75 #define MMC0CKCR 0xE6150240
76 #define MMC1CKCR 0xE6150244
77 #define SSPCKCR 0xE6150248
78 #define SSPRSCKCR 0xE615024C
80 static struct clk_mapping cpg_mapping = {
85 static struct clk extal_clk = {
86 /* .rate will be updated on r8a7791_clock_init() */
87 .mapping = &cpg_mapping,
90 static struct sh_clk_ops followparent_clk_ops = {
91 .recalc = followparent_recalc,
94 static struct clk main_clk = {
95 /* .parent will be set r8a73a4_clock_init */
96 .ops = &followparent_clk_ops,
100 * clock ratio of these clock will be updated
101 * on r8a7791_clock_init()
103 SH_FIXED_RATIO_CLK_SET(pll1_clk, main_clk, 1, 1);
104 SH_FIXED_RATIO_CLK_SET(pll3_clk, main_clk, 1, 1);
105 SH_FIXED_RATIO_CLK_SET(qspi_clk, pll1_clk, 1, 1);
107 /* fixed ratio clock */
108 SH_FIXED_RATIO_CLK_SET(extal_div2_clk, extal_clk, 1, 2);
109 SH_FIXED_RATIO_CLK_SET(cp_clk, extal_clk, 1, 2);
111 SH_FIXED_RATIO_CLK_SET(pll1_div2_clk, pll1_clk, 1, 2);
112 SH_FIXED_RATIO_CLK_SET(hp_clk, pll1_clk, 1, 12);
113 SH_FIXED_RATIO_CLK_SET(p_clk, pll1_clk, 1, 24);
114 SH_FIXED_RATIO_CLK_SET(rclk_clk, pll1_clk, 1, (48 * 1024));
115 SH_FIXED_RATIO_CLK_SET(mp_clk, pll1_div2_clk, 1, 15);
116 SH_FIXED_RATIO_CLK_SET(zg_clk, pll1_clk, 1, 3);
117 SH_FIXED_RATIO_CLK_SET(zx_clk, pll1_clk, 1, 3);
118 SH_FIXED_RATIO_CLK_SET(zs_clk, pll1_clk, 1, 6);
120 static struct clk *main_clks[] = {
138 /* SDHI (DIV4) clock */
139 static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18, 24, 0, 36, 48, 10 };
141 static struct clk_div_mult_table div4_div_mult_table = {
142 .divisors = divisors,
143 .nr_divisors = ARRAY_SIZE(divisors),
146 static struct clk_div4_table div4_table = {
147 .div_mult_table = &div4_div_mult_table,
155 static struct clk div4_clks[DIV4_NR] = {
156 [DIV4_SDH] = SH_CLK_DIV4(&pll1_clk, SDCKCR, 8, 0x0dff, CLK_ENABLE_ON_INIT),
157 [DIV4_SD0] = SH_CLK_DIV4(&pll1_clk, SDCKCR, 4, 0x1de0, CLK_ENABLE_ON_INIT),
166 static struct clk div6_clks[DIV6_NR] = {
167 [DIV6_SD1] = SH_CLK_DIV6(&pll1_div2_clk, SD1CKCR, 0),
168 [DIV6_SD2] = SH_CLK_DIV6(&pll1_div2_clk, SD2CKCR, 0),
173 MSTP931, MSTP930, MSTP929, MSTP928, MSTP927, MSTP925,
177 MSTP811, MSTP810, MSTP809,
178 MSTP726, MSTP724, MSTP723, MSTP721, MSTP720,
179 MSTP719, MSTP718, MSTP715, MSTP714,
181 MSTP314, MSTP312, MSTP311,
182 MSTP216, MSTP207, MSTP206,
183 MSTP204, MSTP203, MSTP202, MSTP1105, MSTP1106, MSTP1107,
188 static struct clk mstp_clks[MSTP_NR] = {
189 [MSTP931] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 31, MSTPSR9, 0), /* I2C0 */
190 [MSTP930] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 30, MSTPSR9, 0), /* I2C1 */
191 [MSTP929] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 29, MSTPSR9, 0), /* I2C2 */
192 [MSTP928] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 28, MSTPSR9, 0), /* I2C3 */
193 [MSTP927] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 27, MSTPSR9, 0), /* I2C4 */
194 [MSTP925] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 25, MSTPSR9, 0), /* I2C5 */
195 [MSTP917] = SH_CLK_MSTP32_STS(&qspi_clk, SMSTPCR9, 17, MSTPSR9, 0), /* QSPI */
196 [MSTP815] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 15, MSTPSR8, 0), /* SATA0 */
197 [MSTP814] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 14, MSTPSR8, 0), /* SATA1 */
198 [MSTP813] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR8, 13, MSTPSR8, 0), /* Ether */
199 [MSTP811] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 11, MSTPSR8, 0), /* VIN0 */
200 [MSTP810] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 10, MSTPSR8, 0), /* VIN1 */
201 [MSTP809] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 9, MSTPSR8, 0), /* VIN2 */
202 [MSTP726] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 26, MSTPSR7, 0), /* LVDS0 */
203 [MSTP724] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 24, MSTPSR7, 0), /* DU0 */
204 [MSTP723] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 23, MSTPSR7, 0), /* DU1 */
205 [MSTP721] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 21, MSTPSR7, 0), /* SCIF0 */
206 [MSTP720] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 20, MSTPSR7, 0), /* SCIF1 */
207 [MSTP719] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 19, MSTPSR7, 0), /* SCIF2 */
208 [MSTP718] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 18, MSTPSR7, 0), /* SCIF3 */
209 [MSTP715] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 15, MSTPSR7, 0), /* SCIF4 */
210 [MSTP714] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 14, MSTPSR7, 0), /* SCIF5 */
211 [MSTP522] = SH_CLK_MSTP32_STS(&extal_clk, SMSTPCR5, 22, MSTPSR5, 0), /* Thermal */
212 [MSTP314] = SH_CLK_MSTP32_STS(&div4_clks[DIV4_SD0], SMSTPCR3, 14, MSTPSR3, 0), /* SDHI0 */
213 [MSTP312] = SH_CLK_MSTP32_STS(&div6_clks[DIV6_SD1], SMSTPCR3, 12, MSTPSR3, 0), /* SDHI1 */
214 [MSTP311] = SH_CLK_MSTP32_STS(&div6_clks[DIV6_SD2], SMSTPCR3, 11, MSTPSR3, 0), /* SDHI2 */
215 [MSTP216] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 16, MSTPSR2, 0), /* SCIFB2 */
216 [MSTP207] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 7, MSTPSR2, 0), /* SCIFB1 */
217 [MSTP206] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 6, MSTPSR2, 0), /* SCIFB0 */
218 [MSTP204] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 4, MSTPSR2, 0), /* SCIFA0 */
219 [MSTP203] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 3, MSTPSR2, 0), /* SCIFA1 */
220 [MSTP202] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 2, MSTPSR2, 0), /* SCIFA2 */
221 [MSTP1105] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR11, 5, MSTPSR11, 0), /* SCIFA3 */
222 [MSTP1106] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR11, 6, MSTPSR11, 0), /* SCIFA4 */
223 [MSTP1107] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR11, 7, MSTPSR11, 0), /* SCIFA5 */
224 [MSTP124] = SH_CLK_MSTP32_STS(&rclk_clk, SMSTPCR1, 24, MSTPSR1, 0), /* CMT0 */
227 static struct clk_lookup lookups[] = {
230 CLKDEV_CON_ID("extal", &extal_clk),
231 CLKDEV_CON_ID("extal_div2", &extal_div2_clk),
232 CLKDEV_CON_ID("main", &main_clk),
233 CLKDEV_CON_ID("pll1", &pll1_clk),
234 CLKDEV_CON_ID("pll1_div2", &pll1_div2_clk),
235 CLKDEV_CON_ID("pll3", &pll3_clk),
236 CLKDEV_CON_ID("zg", &zg_clk),
237 CLKDEV_CON_ID("zs", &zs_clk),
238 CLKDEV_CON_ID("hp", &hp_clk),
239 CLKDEV_CON_ID("p", &p_clk),
240 CLKDEV_CON_ID("qspi", &qspi_clk),
241 CLKDEV_CON_ID("rclk", &rclk_clk),
242 CLKDEV_CON_ID("mp", &mp_clk),
243 CLKDEV_CON_ID("cp", &cp_clk),
244 CLKDEV_CON_ID("peripheral_clk", &hp_clk),
247 CLKDEV_ICK_ID("lvds.0", "rcar-du-r8a7791", &mstp_clks[MSTP726]),
248 CLKDEV_ICK_ID("du.0", "rcar-du-r8a7791", &mstp_clks[MSTP724]),
249 CLKDEV_ICK_ID("du.1", "rcar-du-r8a7791", &mstp_clks[MSTP723]),
250 CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
251 CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
252 CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP206]), /* SCIFB0 */
253 CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP207]), /* SCIFB1 */
254 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP216]), /* SCIFB2 */
255 CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP202]), /* SCIFA2 */
256 CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP721]), /* SCIF0 */
257 CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP720]), /* SCIF1 */
258 CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP719]), /* SCIF2 */
259 CLKDEV_DEV_ID("sh-sci.9", &mstp_clks[MSTP718]), /* SCIF3 */
260 CLKDEV_DEV_ID("sh-sci.10", &mstp_clks[MSTP715]), /* SCIF4 */
261 CLKDEV_DEV_ID("sh-sci.11", &mstp_clks[MSTP714]), /* SCIF5 */
262 CLKDEV_DEV_ID("sh-sci.12", &mstp_clks[MSTP1105]), /* SCIFA3 */
263 CLKDEV_DEV_ID("sh-sci.13", &mstp_clks[MSTP1106]), /* SCIFA4 */
264 CLKDEV_DEV_ID("sh-sci.14", &mstp_clks[MSTP1107]), /* SCIFA5 */
265 CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]),
266 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP312]),
267 CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]),
268 CLKDEV_DEV_ID("sh_cmt.0", &mstp_clks[MSTP124]),
269 CLKDEV_DEV_ID("qspi.0", &mstp_clks[MSTP917]),
270 CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]),
271 CLKDEV_DEV_ID("i2c-rcar_gen2.0", &mstp_clks[MSTP931]),
272 CLKDEV_DEV_ID("i2c-rcar_gen2.1", &mstp_clks[MSTP930]),
273 CLKDEV_DEV_ID("i2c-rcar_gen2.2", &mstp_clks[MSTP929]),
274 CLKDEV_DEV_ID("i2c-rcar_gen2.3", &mstp_clks[MSTP928]),
275 CLKDEV_DEV_ID("i2c-rcar_gen2.4", &mstp_clks[MSTP927]),
276 CLKDEV_DEV_ID("i2c-rcar_gen2.5", &mstp_clks[MSTP925]),
277 CLKDEV_DEV_ID("r8a7791-ether", &mstp_clks[MSTP813]), /* Ether */
278 CLKDEV_DEV_ID("r8a7791-vin.0", &mstp_clks[MSTP811]),
279 CLKDEV_DEV_ID("r8a7791-vin.1", &mstp_clks[MSTP810]),
280 CLKDEV_DEV_ID("r8a7791-vin.2", &mstp_clks[MSTP809]),
281 CLKDEV_DEV_ID("sata-r8a7791.0", &mstp_clks[MSTP815]),
282 CLKDEV_DEV_ID("sata-r8a7791.1", &mstp_clks[MSTP814]),
285 #define R8A7791_CLOCK_ROOT(e, m, p0, p1, p30, p31) \
286 extal_clk.rate = e * 1000 * 1000; \
287 main_clk.parent = m; \
288 SH_CLK_SET_RATIO(&pll1_clk_ratio, p1 / 2, 1); \
290 SH_CLK_SET_RATIO(&pll3_clk_ratio, p31, 1); \
292 SH_CLK_SET_RATIO(&pll3_clk_ratio, p30, 1)
295 void __init r8a7791_clock_init(void)
297 void __iomem *modemr = ioremap_nocache(MODEMR, PAGE_SIZE);
302 mode = ioread32(modemr);
305 switch (mode & (MD(14) | MD(13))) {
307 R8A7791_CLOCK_ROOT(15, &extal_clk, 172, 208, 106, 88);
310 R8A7791_CLOCK_ROOT(20, &extal_clk, 130, 156, 80, 66);
313 R8A7791_CLOCK_ROOT(26, &extal_div2_clk, 200, 240, 122, 102);
315 case MD(13) | MD(14):
316 R8A7791_CLOCK_ROOT(30, &extal_div2_clk, 172, 208, 106, 88);
320 if ((mode & (MD(3) | MD(2) | MD(1))) == MD(2))
321 SH_CLK_SET_RATIO(&qspi_clk_ratio, 1, 16);
323 SH_CLK_SET_RATIO(&qspi_clk_ratio, 1, 20);
325 for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
326 ret = clk_register(main_clks[k]);
329 ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
332 ret = sh_clk_div6_register(div6_clks, DIV6_NR);
335 ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
337 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
347 panic("failed to setup r8a7791 clocks\n");