1 /*
2 * r8a7779 clock framework support
3 *
4 * Copyright (C) 2011 Renesas Solutions Corp.
5 * Copyright (C) 2011 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; either 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20 #include <linux/bitops.h>
21 #include <linux/init.h>
22 #include <linux/kernel.h>
23 #include <linux/io.h>
24 #include <linux/sh_clk.h>
25 #include <linux/clkdev.h>
26 #include <linux/sh_timer.h>
27
28 #include "clock.h"
29 #include "common.h"
30 #include "r8a7779.h"
31
32 /*
33 * MD1 = 1 MD1 = 0
34 * (PLLA = 1500) (PLLA = 1600)
35 * (MHz) (MHz)
36 *------------------------------------------------+--------------------
37 * clkz 1000 (2/3) 800 (1/2)
38 * clkzs 250 (1/6) 200 (1/8)
39 * clki 750 (1/2) 800 (1/2)
40 * clks 250 (1/6) 200 (1/8)
41 * clks1 125 (1/12) 100 (1/16)
42 * clks3 187.5 (1/8) 200 (1/8)
43 * clks4 93.7 (1/16) 100 (1/16)
44 * clkp 62.5 (1/24) 50 (1/32)
45 * clkg 62.5 (1/24) 66.6 (1/24)
46 * clkb, CLKOUT
47 * (MD2 = 0) 62.5 (1/24) 66.6 (1/24)
48 * (MD2 = 1) 41.6 (1/36) 50 (1/32)
49 */
50
51 #define MD(nr) BIT(nr)
52
53 #define MSTPCR0 IOMEM(0xffc80030)
54 #define MSTPCR1 IOMEM(0xffc80034)
55 #define MSTPCR3 IOMEM(0xffc8003c)
56 #define MSTPSR1 IOMEM(0xffc80044)
57
58 /* ioremap() through clock mapping mandatory to avoid
59 * collision with ARM coherent DMA virtual memory range.
60 */
61
62 static struct clk_mapping cpg_mapping = {
63 .phys = 0xffc80000,
64 .len = 0x80,
65 };
66
67 /*
68 * Default rate for the root input clock, reset this with clk_set_rate()
69 * from the platform code.
70 */
71 static struct clk plla_clk = {
72 /* .rate will be updated on r8a7779_clock_init() */
73 .mapping = &cpg_mapping,
74 };
75
76 /*
77 * clock ratio of these clock will be updated
78 * on r8a7779_clock_init()
79 */
80 SH_FIXED_RATIO_CLK_SET(clkz_clk, plla_clk, 1, 1);
81 SH_FIXED_RATIO_CLK_SET(clkzs_clk, plla_clk, 1, 1);
82 SH_FIXED_RATIO_CLK_SET(clki_clk, plla_clk, 1, 1);
83 SH_FIXED_RATIO_CLK_SET(clks_clk, plla_clk, 1, 1);
84 SH_FIXED_RATIO_CLK_SET(clks1_clk, plla_clk, 1, 1);
85 SH_FIXED_RATIO_CLK_SET(clks3_clk, plla_clk, 1, 1);
86 SH_FIXED_RATIO_CLK_SET(clks4_clk, plla_clk, 1, 1);
87 SH_FIXED_RATIO_CLK_SET(clkb_clk, plla_clk, 1, 1);
88 SH_FIXED_RATIO_CLK_SET(clkout_clk, plla_clk, 1, 1);
89 SH_FIXED_RATIO_CLK_SET(clkp_clk, plla_clk, 1, 1);
90 SH_FIXED_RATIO_CLK_SET(clkg_clk, plla_clk, 1, 1);
91
92 static struct clk *main_clks[] = {
93 &plla_clk,
94 &clkz_clk,
95 &clkzs_clk,
96 &clki_clk,
97 &clks_clk,
98 &clks1_clk,
99 &clks3_clk,
100 &clks4_clk,
101 &clkb_clk,
102 &clkout_clk,
103 &clkp_clk,
104 &clkg_clk,
105 };
106
107 enum { MSTP323, MSTP322, MSTP321, MSTP320,
108 MSTP120,
109 MSTP116, MSTP115, MSTP114,
110 MSTP110, MSTP109, MSTP108,
111 MSTP103, MSTP101, MSTP100,
112 MSTP030,
113 MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021,
114 MSTP016, MSTP015, MSTP014,
115 MSTP007,
116 MSTP_NR };
117
118 static struct clk mstp_clks[MSTP_NR] = {
119 [MSTP323] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 23, 0), /* SDHI0 */
120 [MSTP322] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 22, 0), /* SDHI1 */
121 [MSTP321] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 21, 0), /* SDHI2 */
122 [MSTP320] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 20, 0), /* SDHI3 */
123 [MSTP120] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1, 20, MSTPSR1, 0), /* VIN3 */
124 [MSTP116] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 16, MSTPSR1, 0), /* PCIe */
125 [MSTP115] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 15, MSTPSR1, 0), /* SATA */
126 [MSTP114] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 14, MSTPSR1, 0), /* Ether */
127 [MSTP110] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1, 10, MSTPSR1, 0), /* VIN0 */
128 [MSTP109] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1, 9, MSTPSR1, 0), /* VIN1 */
129 [MSTP108] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1, 8, MSTPSR1, 0), /* VIN2 */
130 [MSTP103] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1, 3, MSTPSR1, 0), /* DU */
131 [MSTP101] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 1, MSTPSR1, 0), /* USB2 */
132 [MSTP100] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 0, MSTPSR1, 0), /* USB0/1 */
133 [MSTP030] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 30, 0), /* I2C0 */
134 [MSTP029] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 29, 0), /* I2C1 */
135 [MSTP028] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 28, 0), /* I2C2 */
136 [MSTP027] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 27, 0), /* I2C3 */
137 [MSTP026] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 26, 0), /* SCIF0 */
138 [MSTP025] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 25, 0), /* SCIF1 */
139 [MSTP024] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 24, 0), /* SCIF2 */
140 [MSTP023] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 23, 0), /* SCIF3 */
141 [MSTP022] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 22, 0), /* SCIF4 */
142 [MSTP021] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 21, 0), /* SCIF5 */
143 [MSTP016] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 16, 0), /* TMU0 */
144 [MSTP015] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 15, 0), /* TMU1 */
145 [MSTP014] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 14, 0), /* TMU2 */
146 [MSTP007] = SH_CLK_MSTP32(&clks_clk, MSTPCR0, 7, 0), /* HSPI */
147 };
148
149 static struct clk_lookup lookups[] = {
150 /* main clocks */
151 CLKDEV_CON_ID("plla_clk", &plla_clk),
152 CLKDEV_CON_ID("clkz_clk", &clkz_clk),
153 CLKDEV_CON_ID("clkzs_clk", &clkzs_clk),
154
155 /* DIV4 clocks */
156 CLKDEV_CON_ID("shyway_clk", &clks_clk),
157 CLKDEV_CON_ID("bus_clk", &clkout_clk),
158 CLKDEV_CON_ID("shyway4_clk", &clks4_clk),
159 CLKDEV_CON_ID("shyway3_clk", &clks3_clk),
160 CLKDEV_CON_ID("shyway1_clk", &clks1_clk),
161 CLKDEV_CON_ID("peripheral_clk", &clkp_clk),
162
163 /* MSTP32 clocks */
164 CLKDEV_DEV_ID("r8a7779-vin.3", &mstp_clks[MSTP120]), /* VIN3 */
165 CLKDEV_DEV_ID("rcar-pcie", &mstp_clks[MSTP116]), /* PCIe */
166 CLKDEV_DEV_ID("sata_rcar", &mstp_clks[MSTP115]), /* SATA */
167 CLKDEV_DEV_ID("fc600000.sata", &mstp_clks[MSTP115]), /* SATA w/DT */
168 CLKDEV_DEV_ID("r8a777x-ether", &mstp_clks[MSTP114]), /* Ether */
169 CLKDEV_DEV_ID("r8a7779-vin.0", &mstp_clks[MSTP110]), /* VIN0 */
170 CLKDEV_DEV_ID("r8a7779-vin.1", &mstp_clks[MSTP109]), /* VIN1 */
171 CLKDEV_DEV_ID("r8a7779-vin.2", &mstp_clks[MSTP108]), /* VIN2 */
172 CLKDEV_DEV_ID("ehci-platform.1", &mstp_clks[MSTP101]), /* USB EHCI port2 */
173 CLKDEV_DEV_ID("ohci-platform.1", &mstp_clks[MSTP101]), /* USB OHCI port2 */
174 CLKDEV_DEV_ID("ehci-platform.0", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */
175 CLKDEV_DEV_ID("ohci-platform.0", &mstp_clks[MSTP100]), /* USB OHCI port0/1 */
176 CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[MSTP016]), /* TMU0 */
177 CLKDEV_DEV_ID("i2c-rcar.0", &mstp_clks[MSTP030]), /* I2C0 */
178 CLKDEV_DEV_ID("ffc70000.i2c", &mstp_clks[MSTP030]), /* I2C0 */
179 CLKDEV_DEV_ID("i2c-rcar.1", &mstp_clks[MSTP029]), /* I2C1 */
180 CLKDEV_DEV_ID("ffc71000.i2c", &mstp_clks[MSTP029]), /* I2C1 */
181 CLKDEV_DEV_ID("i2c-rcar.2", &mstp_clks[MSTP028]), /* I2C2 */
182 CLKDEV_DEV_ID("ffc72000.i2c", &mstp_clks[MSTP028]), /* I2C2 */
183 CLKDEV_DEV_ID("i2c-rcar.3", &mstp_clks[MSTP027]), /* I2C3 */
184 CLKDEV_DEV_ID("ffc73000.i2c", &mstp_clks[MSTP027]), /* I2C3 */
185 CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP026]), /* SCIF0 */
186 CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP025]), /* SCIF1 */
187 CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP024]), /* SCIF2 */
188 CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP023]), /* SCIF3 */
189 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP022]), /* SCIF4 */
190 CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP021]), /* SCIF6 */
191 CLKDEV_DEV_ID("sh-hspi.0", &mstp_clks[MSTP007]), /* HSPI0 */
192 CLKDEV_DEV_ID("fffc7000.spi", &mstp_clks[MSTP007]), /* HSPI0 */
193 CLKDEV_DEV_ID("sh-hspi.1", &mstp_clks[MSTP007]), /* HSPI1 */
194 CLKDEV_DEV_ID("fffc8000.spi", &mstp_clks[MSTP007]), /* HSPI1 */
195 CLKDEV_DEV_ID("sh-hspi.2", &mstp_clks[MSTP007]), /* HSPI2 */
196 CLKDEV_DEV_ID("fffc6000.spi", &mstp_clks[MSTP007]), /* HSPI2 */
197 CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP323]), /* SDHI0 */
198 CLKDEV_DEV_ID("ffe4c000.sd", &mstp_clks[MSTP323]), /* SDHI0 */
199 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */
200 CLKDEV_DEV_ID("ffe4d000.sd", &mstp_clks[MSTP322]), /* SDHI1 */
201 CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */
202 CLKDEV_DEV_ID("ffe4e000.sd", &mstp_clks[MSTP321]), /* SDHI2 */
203 CLKDEV_DEV_ID("sh_mobile_sdhi.3", &mstp_clks[MSTP320]), /* SDHI3 */
204 CLKDEV_DEV_ID("ffe4f000.sd", &mstp_clks[MSTP320]), /* SDHI3 */
205 CLKDEV_DEV_ID("rcar-du-r8a7779", &mstp_clks[MSTP103]), /* DU */
206 };
207
r8a7779_clock_init(void)208 void __init r8a7779_clock_init(void)
209 {
210 u32 mode = r8a7779_read_mode_pins();
211 int k, ret = 0;
212
213 if (mode & MD(1)) {
214 plla_clk.rate = 1500000000;
215
216 SH_CLK_SET_RATIO(&clkz_clk_ratio, 2, 3);
217 SH_CLK_SET_RATIO(&clkzs_clk_ratio, 1, 6);
218 SH_CLK_SET_RATIO(&clki_clk_ratio, 1, 2);
219 SH_CLK_SET_RATIO(&clks_clk_ratio, 1, 6);
220 SH_CLK_SET_RATIO(&clks1_clk_ratio, 1, 12);
221 SH_CLK_SET_RATIO(&clks3_clk_ratio, 1, 8);
222 SH_CLK_SET_RATIO(&clks4_clk_ratio, 1, 16);
223 SH_CLK_SET_RATIO(&clkp_clk_ratio, 1, 24);
224 SH_CLK_SET_RATIO(&clkg_clk_ratio, 1, 24);
225 if (mode & MD(2)) {
226 SH_CLK_SET_RATIO(&clkb_clk_ratio, 1, 36);
227 SH_CLK_SET_RATIO(&clkout_clk_ratio, 1, 36);
228 } else {
229 SH_CLK_SET_RATIO(&clkb_clk_ratio, 1, 24);
230 SH_CLK_SET_RATIO(&clkout_clk_ratio, 1, 24);
231 }
232 } else {
233 plla_clk.rate = 1600000000;
234
235 SH_CLK_SET_RATIO(&clkz_clk_ratio, 1, 2);
236 SH_CLK_SET_RATIO(&clkzs_clk_ratio, 1, 8);
237 SH_CLK_SET_RATIO(&clki_clk_ratio, 1, 2);
238 SH_CLK_SET_RATIO(&clks_clk_ratio, 1, 8);
239 SH_CLK_SET_RATIO(&clks1_clk_ratio, 1, 16);
240 SH_CLK_SET_RATIO(&clks3_clk_ratio, 1, 8);
241 SH_CLK_SET_RATIO(&clks4_clk_ratio, 1, 16);
242 SH_CLK_SET_RATIO(&clkp_clk_ratio, 1, 32);
243 SH_CLK_SET_RATIO(&clkg_clk_ratio, 1, 24);
244 if (mode & MD(2)) {
245 SH_CLK_SET_RATIO(&clkb_clk_ratio, 1, 32);
246 SH_CLK_SET_RATIO(&clkout_clk_ratio, 1, 32);
247 } else {
248 SH_CLK_SET_RATIO(&clkb_clk_ratio, 1, 24);
249 SH_CLK_SET_RATIO(&clkout_clk_ratio, 1, 24);
250 }
251 }
252
253 for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
254 ret = clk_register(main_clks[k]);
255
256 if (!ret)
257 ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
258
259 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
260
261 if (!ret)
262 shmobile_clk_init();
263 else
264 panic("failed to setup r8a7779 clocks\n");
265 }
266
267 /* do nothing for !CONFIG_SMP or !CONFIG_HAVE_TWD */
r8a7779_register_twd(void)268 void __init __weak r8a7779_register_twd(void) { }
269
r8a7779_earlytimer_init(void)270 void __init r8a7779_earlytimer_init(void)
271 {
272 r8a7779_clock_init();
273 r8a7779_register_twd();
274 shmobile_earlytimer_init();
275 }
276