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 MSTP1108, MSTP1107, MSTP1106,
174 MSTP931, MSTP930, MSTP929, MSTP928, MSTP927, MSTP925,
178 MSTP811, MSTP810, MSTP809,
179 MSTP726, MSTP724, MSTP723, MSTP721, MSTP720,
180 MSTP719, MSTP718, MSTP715, MSTP714,
182 MSTP314, MSTP312, MSTP311,
183 MSTP216, MSTP207, MSTP206,
184 MSTP204, MSTP203, MSTP202,
189 static struct clk mstp_clks[MSTP_NR] = {
190 [MSTP1108] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR11, 8, MSTPSR11, 0), /* SCIFA5 */
191 [MSTP1107] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR11, 7, MSTPSR11, 0), /* SCIFA4 */
192 [MSTP1106] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR11, 6, MSTPSR11, 0), /* SCIFA3 */
193 [MSTP931] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 31, MSTPSR9, 0), /* I2C0 */
194 [MSTP930] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 30, MSTPSR9, 0), /* I2C1 */
195 [MSTP929] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 29, MSTPSR9, 0), /* I2C2 */
196 [MSTP928] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 28, MSTPSR9, 0), /* I2C3 */
197 [MSTP927] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 27, MSTPSR9, 0), /* I2C4 */
198 [MSTP925] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 25, MSTPSR9, 0), /* I2C5 */
199 [MSTP917] = SH_CLK_MSTP32_STS(&qspi_clk, SMSTPCR9, 17, MSTPSR9, 0), /* QSPI */
200 [MSTP815] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 15, MSTPSR8, 0), /* SATA0 */
201 [MSTP814] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 14, MSTPSR8, 0), /* SATA1 */
202 [MSTP813] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR8, 13, MSTPSR8, 0), /* Ether */
203 [MSTP811] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 11, MSTPSR8, 0), /* VIN0 */
204 [MSTP810] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 10, MSTPSR8, 0), /* VIN1 */
205 [MSTP809] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 9, MSTPSR8, 0), /* VIN2 */
206 [MSTP726] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 26, MSTPSR7, 0), /* LVDS0 */
207 [MSTP724] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 24, MSTPSR7, 0), /* DU0 */
208 [MSTP723] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 23, MSTPSR7, 0), /* DU1 */
209 [MSTP721] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 21, MSTPSR7, 0), /* SCIF0 */
210 [MSTP720] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 20, MSTPSR7, 0), /* SCIF1 */
211 [MSTP719] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 19, MSTPSR7, 0), /* SCIF2 */
212 [MSTP718] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 18, MSTPSR7, 0), /* SCIF3 */
213 [MSTP715] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 15, MSTPSR7, 0), /* SCIF4 */
214 [MSTP714] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 14, MSTPSR7, 0), /* SCIF5 */
215 [MSTP522] = SH_CLK_MSTP32_STS(&extal_clk, SMSTPCR5, 22, MSTPSR5, 0), /* Thermal */
216 [MSTP314] = SH_CLK_MSTP32_STS(&div4_clks[DIV4_SD0], SMSTPCR3, 14, MSTPSR3, 0), /* SDHI0 */
217 [MSTP312] = SH_CLK_MSTP32_STS(&div6_clks[DIV6_SD1], SMSTPCR3, 12, MSTPSR3, 0), /* SDHI1 */
218 [MSTP311] = SH_CLK_MSTP32_STS(&div6_clks[DIV6_SD2], SMSTPCR3, 11, MSTPSR3, 0), /* SDHI2 */
219 [MSTP216] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 16, MSTPSR2, 0), /* SCIFB2 */
220 [MSTP207] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 7, MSTPSR2, 0), /* SCIFB1 */
221 [MSTP206] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 6, MSTPSR2, 0), /* SCIFB0 */
222 [MSTP204] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 4, MSTPSR2, 0), /* SCIFA0 */
223 [MSTP203] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 3, MSTPSR2, 0), /* SCIFA1 */
224 [MSTP202] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 2, MSTPSR2, 0), /* SCIFA2 */
225 [MSTP124] = SH_CLK_MSTP32_STS(&rclk_clk, SMSTPCR1, 24, MSTPSR1, 0), /* CMT0 */
228 static struct clk_lookup lookups[] = {
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("zs", &zs_clk),
239 CLKDEV_CON_ID("hp", &hp_clk),
240 CLKDEV_CON_ID("p", &p_clk),
241 CLKDEV_CON_ID("qspi", &qspi_clk),
242 CLKDEV_CON_ID("rclk", &rclk_clk),
243 CLKDEV_CON_ID("mp", &mp_clk),
244 CLKDEV_CON_ID("cp", &cp_clk),
245 CLKDEV_CON_ID("peripheral_clk", &hp_clk),
248 CLKDEV_ICK_ID("lvds.0", "rcar-du-r8a7791", &mstp_clks[MSTP726]),
249 CLKDEV_ICK_ID("du.0", "rcar-du-r8a7791", &mstp_clks[MSTP724]),
250 CLKDEV_ICK_ID("du.1", "rcar-du-r8a7791", &mstp_clks[MSTP723]),
251 CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
252 CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
253 CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP206]), /* SCIFB0 */
254 CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP207]), /* SCIFB1 */
255 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP216]), /* SCIFB2 */
256 CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP202]), /* SCIFA2 */
257 CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP721]), /* SCIF0 */
258 CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP720]), /* SCIF1 */
259 CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP719]), /* SCIF2 */
260 CLKDEV_DEV_ID("sh-sci.9", &mstp_clks[MSTP718]), /* SCIF3 */
261 CLKDEV_DEV_ID("sh-sci.10", &mstp_clks[MSTP715]), /* SCIF4 */
262 CLKDEV_DEV_ID("sh-sci.11", &mstp_clks[MSTP714]), /* SCIF5 */
263 CLKDEV_DEV_ID("sh-sci.12", &mstp_clks[MSTP1106]), /* SCIFA3 */
264 CLKDEV_DEV_ID("sh-sci.13", &mstp_clks[MSTP1107]), /* SCIFA4 */
265 CLKDEV_DEV_ID("sh-sci.14", &mstp_clks[MSTP1108]), /* SCIFA5 */
266 CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]),
267 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP312]),
268 CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]),
269 CLKDEV_DEV_ID("sh_cmt.0", &mstp_clks[MSTP124]),
270 CLKDEV_DEV_ID("qspi.0", &mstp_clks[MSTP917]),
271 CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]),
272 CLKDEV_DEV_ID("i2c-rcar_gen2.0", &mstp_clks[MSTP931]),
273 CLKDEV_DEV_ID("i2c-rcar_gen2.1", &mstp_clks[MSTP930]),
274 CLKDEV_DEV_ID("i2c-rcar_gen2.2", &mstp_clks[MSTP929]),
275 CLKDEV_DEV_ID("i2c-rcar_gen2.3", &mstp_clks[MSTP928]),
276 CLKDEV_DEV_ID("i2c-rcar_gen2.4", &mstp_clks[MSTP927]),
277 CLKDEV_DEV_ID("i2c-rcar_gen2.5", &mstp_clks[MSTP925]),
278 CLKDEV_DEV_ID("r8a7791-ether", &mstp_clks[MSTP813]), /* Ether */
279 CLKDEV_DEV_ID("r8a7791-vin.0", &mstp_clks[MSTP811]),
280 CLKDEV_DEV_ID("r8a7791-vin.1", &mstp_clks[MSTP810]),
281 CLKDEV_DEV_ID("r8a7791-vin.2", &mstp_clks[MSTP809]),
282 CLKDEV_DEV_ID("sata-r8a7791.0", &mstp_clks[MSTP815]),
283 CLKDEV_DEV_ID("sata-r8a7791.1", &mstp_clks[MSTP814]),
286 #define R8A7791_CLOCK_ROOT(e, m, p0, p1, p30, p31) \
287 extal_clk.rate = e * 1000 * 1000; \
288 main_clk.parent = m; \
289 SH_CLK_SET_RATIO(&pll1_clk_ratio, p1 / 2, 1); \
291 SH_CLK_SET_RATIO(&pll3_clk_ratio, p31, 1); \
293 SH_CLK_SET_RATIO(&pll3_clk_ratio, p30, 1)
296 void __init r8a7791_clock_init(void)
298 void __iomem *modemr = ioremap_nocache(MODEMR, PAGE_SIZE);
303 mode = ioread32(modemr);
306 switch (mode & (MD(14) | MD(13))) {
308 R8A7791_CLOCK_ROOT(15, &extal_clk, 172, 208, 106, 88);
311 R8A7791_CLOCK_ROOT(20, &extal_clk, 130, 156, 80, 66);
314 R8A7791_CLOCK_ROOT(26, &extal_div2_clk, 200, 240, 122, 102);
316 case MD(13) | MD(14):
317 R8A7791_CLOCK_ROOT(30, &extal_div2_clk, 172, 208, 106, 88);
321 if ((mode & (MD(3) | MD(2) | MD(1))) == MD(2))
322 SH_CLK_SET_RATIO(&qspi_clk_ratio, 1, 16);
324 SH_CLK_SET_RATIO(&qspi_clk_ratio, 1, 20);
326 for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
327 ret = clk_register(main_clks[k]);
330 ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
333 ret = sh_clk_div6_register(div6_clks, DIV6_NR);
336 ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
338 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
348 panic("failed to setup r8a7791 clocks\n");