diff options
Diffstat (limited to 'arch/arm/mach-shmobile/clock-r8a73a4.c')
-rw-r--r-- | arch/arm/mach-shmobile/clock-r8a73a4.c | 387 |
1 files changed, 371 insertions, 16 deletions
diff --git a/arch/arm/mach-shmobile/clock-r8a73a4.c b/arch/arm/mach-shmobile/clock-r8a73a4.c index e710c00c3822..5f7fe628b8a1 100644 --- a/arch/arm/mach-shmobile/clock-r8a73a4.c +++ b/arch/arm/mach-shmobile/clock-r8a73a4.c | |||
@@ -22,15 +22,44 @@ | |||
22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
23 | #include <linux/sh_clk.h> | 23 | #include <linux/sh_clk.h> |
24 | #include <linux/clkdev.h> | 24 | #include <linux/clkdev.h> |
25 | #include <mach/clock.h> | ||
25 | #include <mach/common.h> | 26 | #include <mach/common.h> |
26 | 27 | ||
27 | #define CPG_BASE 0xe6150000 | 28 | #define CPG_BASE 0xe6150000 |
28 | #define CPG_LEN 0x270 | 29 | #define CPG_LEN 0x270 |
29 | 30 | ||
30 | #define MPCKCR 0xe6150080 | ||
31 | #define SMSTPCR2 0xe6150138 | 31 | #define SMSTPCR2 0xe6150138 |
32 | #define SMSTPCR3 0xe615013c | ||
32 | #define SMSTPCR5 0xe6150144 | 33 | #define SMSTPCR5 0xe6150144 |
33 | 34 | ||
35 | #define FRQCRA 0xE6150000 | ||
36 | #define FRQCRB 0xE6150004 | ||
37 | #define VCLKCR1 0xE6150008 | ||
38 | #define VCLKCR2 0xE615000C | ||
39 | #define VCLKCR3 0xE615001C | ||
40 | #define VCLKCR4 0xE6150014 | ||
41 | #define VCLKCR5 0xE6150034 | ||
42 | #define ZBCKCR 0xE6150010 | ||
43 | #define SD0CKCR 0xE6150074 | ||
44 | #define SD1CKCR 0xE6150078 | ||
45 | #define SD2CKCR 0xE615007C | ||
46 | #define MMC0CKCR 0xE6150240 | ||
47 | #define MMC1CKCR 0xE6150244 | ||
48 | #define FSIACKCR 0xE6150018 | ||
49 | #define FSIBCKCR 0xE6150090 | ||
50 | #define MPCKCR 0xe6150080 | ||
51 | #define SPUVCKCR 0xE6150094 | ||
52 | #define HSICKCR 0xE615026C | ||
53 | #define M4CKCR 0xE6150098 | ||
54 | #define PLLECR 0xE61500D0 | ||
55 | #define PLL1CR 0xE6150028 | ||
56 | #define PLL2CR 0xE615002C | ||
57 | #define PLL2SCR 0xE61501F4 | ||
58 | #define PLL2HCR 0xE61501E4 | ||
59 | #define CKSCR 0xE61500C0 | ||
60 | |||
61 | #define CPG_MAP(o) ((o - CPG_BASE) + cpg_mapping.base) | ||
62 | |||
34 | static struct clk_mapping cpg_mapping = { | 63 | static struct clk_mapping cpg_mapping = { |
35 | .phys = CPG_BASE, | 64 | .phys = CPG_BASE, |
36 | .len = CPG_LEN, | 65 | .len = CPG_LEN, |
@@ -51,29 +80,327 @@ static struct clk extal2_clk = { | |||
51 | .mapping = &cpg_mapping, | 80 | .mapping = &cpg_mapping, |
52 | }; | 81 | }; |
53 | 82 | ||
83 | static struct sh_clk_ops followparent_clk_ops = { | ||
84 | .recalc = followparent_recalc, | ||
85 | }; | ||
86 | |||
87 | static struct clk main_clk = { | ||
88 | /* .parent will be set r8a73a4_clock_init */ | ||
89 | .ops = &followparent_clk_ops, | ||
90 | }; | ||
91 | |||
92 | SH_CLK_RATIO(div2, 1, 2); | ||
93 | SH_CLK_RATIO(div4, 1, 4); | ||
94 | |||
95 | SH_FIXED_RATIO_CLK(main_div2_clk, main_clk, div2); | ||
96 | SH_FIXED_RATIO_CLK(extal1_div2_clk, extal1_clk, div2); | ||
97 | SH_FIXED_RATIO_CLK(extal2_div2_clk, extal2_clk, div2); | ||
98 | SH_FIXED_RATIO_CLK(extal2_div4_clk, extal2_clk, div4); | ||
99 | |||
100 | /* External FSIACK/FSIBCK clock */ | ||
101 | static struct clk fsiack_clk = { | ||
102 | }; | ||
103 | |||
104 | static struct clk fsibck_clk = { | ||
105 | }; | ||
106 | |||
107 | /* | ||
108 | * PLL clocks | ||
109 | */ | ||
110 | static struct clk *pll_parent_main[] = { | ||
111 | [0] = &main_clk, | ||
112 | [1] = &main_div2_clk | ||
113 | }; | ||
114 | |||
115 | static struct clk *pll_parent_main_extal[8] = { | ||
116 | [0] = &main_div2_clk, | ||
117 | [1] = &extal2_div2_clk, | ||
118 | [3] = &extal2_div4_clk, | ||
119 | [4] = &main_clk, | ||
120 | [5] = &extal2_clk, | ||
121 | }; | ||
122 | |||
123 | static unsigned long pll_recalc(struct clk *clk) | ||
124 | { | ||
125 | unsigned long mult = 1; | ||
126 | |||
127 | if (ioread32(CPG_MAP(PLLECR)) & (1 << clk->enable_bit)) | ||
128 | mult = (((ioread32(clk->mapped_reg) >> 24) & 0x7f) + 1); | ||
129 | |||
130 | return clk->parent->rate * mult; | ||
131 | } | ||
132 | |||
133 | static int pll_set_parent(struct clk *clk, struct clk *parent) | ||
134 | { | ||
135 | u32 val; | ||
136 | int i, ret; | ||
137 | |||
138 | if (!clk->parent_table || !clk->parent_num) | ||
139 | return -EINVAL; | ||
140 | |||
141 | /* Search the parent */ | ||
142 | for (i = 0; i < clk->parent_num; i++) | ||
143 | if (clk->parent_table[i] == parent) | ||
144 | break; | ||
145 | |||
146 | if (i == clk->parent_num) | ||
147 | return -ENODEV; | ||
148 | |||
149 | ret = clk_reparent(clk, parent); | ||
150 | if (ret < 0) | ||
151 | return ret; | ||
152 | |||
153 | val = ioread32(clk->mapped_reg) & | ||
154 | ~(((1 << clk->src_width) - 1) << clk->src_shift); | ||
155 | |||
156 | iowrite32(val | i << clk->src_shift, clk->mapped_reg); | ||
157 | |||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | static struct sh_clk_ops pll_clk_ops = { | ||
162 | .recalc = pll_recalc, | ||
163 | .set_parent = pll_set_parent, | ||
164 | }; | ||
165 | |||
166 | #define PLL_CLOCK(name, p, pt, w, s, reg, e) \ | ||
167 | static struct clk name = { \ | ||
168 | .ops = &pll_clk_ops, \ | ||
169 | .flags = CLK_ENABLE_ON_INIT, \ | ||
170 | .parent = p, \ | ||
171 | .parent_table = pt, \ | ||
172 | .parent_num = ARRAY_SIZE(pt), \ | ||
173 | .src_width = w, \ | ||
174 | .src_shift = s, \ | ||
175 | .enable_reg = (void __iomem *)reg, \ | ||
176 | .enable_bit = e, \ | ||
177 | .mapping = &cpg_mapping, \ | ||
178 | } | ||
179 | |||
180 | PLL_CLOCK(pll1_clk, &main_clk, pll_parent_main, 1, 7, PLL1CR, 1); | ||
181 | PLL_CLOCK(pll2_clk, &main_div2_clk, pll_parent_main_extal, 3, 5, PLL2CR, 2); | ||
182 | PLL_CLOCK(pll2s_clk, &main_div2_clk, pll_parent_main_extal, 3, 5, PLL2SCR, 4); | ||
183 | PLL_CLOCK(pll2h_clk, &main_div2_clk, pll_parent_main_extal, 3, 5, PLL2HCR, 5); | ||
184 | |||
185 | SH_FIXED_RATIO_CLK(pll1_div2_clk, pll1_clk, div2); | ||
186 | |||
54 | static struct clk *main_clks[] = { | 187 | static struct clk *main_clks[] = { |
55 | &extalr_clk, | 188 | &extalr_clk, |
56 | &extal1_clk, | 189 | &extal1_clk, |
190 | &extal1_div2_clk, | ||
57 | &extal2_clk, | 191 | &extal2_clk, |
192 | &extal2_div2_clk, | ||
193 | &extal2_div4_clk, | ||
194 | &main_clk, | ||
195 | &main_div2_clk, | ||
196 | &fsiack_clk, | ||
197 | &fsibck_clk, | ||
198 | &pll1_clk, | ||
199 | &pll1_div2_clk, | ||
200 | &pll2_clk, | ||
201 | &pll2s_clk, | ||
202 | &pll2h_clk, | ||
203 | }; | ||
204 | |||
205 | /* DIV4 */ | ||
206 | static void div4_kick(struct clk *clk) | ||
207 | { | ||
208 | unsigned long value; | ||
209 | |||
210 | /* set KICK bit in FRQCRB to update hardware setting */ | ||
211 | value = ioread32(CPG_MAP(FRQCRB)); | ||
212 | value |= (1 << 31); | ||
213 | iowrite32(value, CPG_MAP(FRQCRB)); | ||
214 | } | ||
215 | |||
216 | static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18, 24, 0, 36, 48, 10}; | ||
217 | |||
218 | static struct clk_div_mult_table div4_div_mult_table = { | ||
219 | .divisors = divisors, | ||
220 | .nr_divisors = ARRAY_SIZE(divisors), | ||
221 | }; | ||
222 | |||
223 | static struct clk_div4_table div4_table = { | ||
224 | .div_mult_table = &div4_div_mult_table, | ||
225 | .kick = div4_kick, | ||
226 | }; | ||
227 | |||
228 | enum { | ||
229 | DIV4_I, DIV4_M3, DIV4_B, DIV4_M1, DIV4_M2, | ||
230 | DIV4_ZX, DIV4_ZS, DIV4_HP, | ||
231 | DIV4_NR }; | ||
232 | |||
233 | static struct clk div4_clks[DIV4_NR] = { | ||
234 | [DIV4_I] = SH_CLK_DIV4(&pll1_clk, FRQCRA, 20, 0x0dff, CLK_ENABLE_ON_INIT), | ||
235 | [DIV4_M3] = SH_CLK_DIV4(&pll1_clk, FRQCRA, 12, 0x1dff, CLK_ENABLE_ON_INIT), | ||
236 | [DIV4_B] = SH_CLK_DIV4(&pll1_clk, FRQCRA, 8, 0x0dff, CLK_ENABLE_ON_INIT), | ||
237 | [DIV4_M1] = SH_CLK_DIV4(&pll1_clk, FRQCRA, 4, 0x1dff, 0), | ||
238 | [DIV4_M2] = SH_CLK_DIV4(&pll1_clk, FRQCRA, 0, 0x1dff, 0), | ||
239 | [DIV4_ZX] = SH_CLK_DIV4(&pll1_clk, FRQCRB, 12, 0x0dff, 0), | ||
240 | [DIV4_ZS] = SH_CLK_DIV4(&pll1_clk, FRQCRB, 8, 0x0dff, 0), | ||
241 | [DIV4_HP] = SH_CLK_DIV4(&pll1_clk, FRQCRB, 4, 0x0dff, 0), | ||
58 | }; | 242 | }; |
59 | 243 | ||
60 | enum { | 244 | enum { |
245 | DIV6_ZB, | ||
246 | DIV6_SDHI0, DIV6_SDHI1, DIV6_SDHI2, | ||
247 | DIV6_MMC0, DIV6_MMC1, | ||
248 | DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_VCK4, DIV6_VCK5, | ||
249 | DIV6_FSIA, DIV6_FSIB, | ||
250 | DIV6_MP, DIV6_M4, DIV6_HSI, DIV6_SPUV, | ||
251 | DIV6_NR }; | ||
252 | |||
253 | static struct clk *div6_parents[8] = { | ||
254 | [0] = &pll1_div2_clk, | ||
255 | [1] = &pll2s_clk, | ||
256 | [3] = &extal2_clk, | ||
257 | [4] = &main_div2_clk, | ||
258 | [6] = &extalr_clk, | ||
259 | }; | ||
260 | |||
261 | static struct clk *fsia_parents[4] = { | ||
262 | [0] = &pll1_div2_clk, | ||
263 | [1] = &pll2s_clk, | ||
264 | [2] = &fsiack_clk, | ||
265 | }; | ||
266 | |||
267 | static struct clk *fsib_parents[4] = { | ||
268 | [0] = &pll1_div2_clk, | ||
269 | [1] = &pll2s_clk, | ||
270 | [2] = &fsibck_clk, | ||
271 | }; | ||
272 | |||
273 | static struct clk *mp_parents[4] = { | ||
274 | [0] = &pll1_div2_clk, | ||
275 | [1] = &pll2s_clk, | ||
276 | [2] = &extal2_clk, | ||
277 | [3] = &extal2_clk, | ||
278 | }; | ||
279 | |||
280 | static struct clk *m4_parents[2] = { | ||
281 | [0] = &pll2s_clk, | ||
282 | }; | ||
283 | |||
284 | static struct clk *hsi_parents[4] = { | ||
285 | [0] = &pll2h_clk, | ||
286 | [1] = &pll1_div2_clk, | ||
287 | [3] = &pll2s_clk, | ||
288 | }; | ||
289 | |||
290 | /*** FIXME *** | ||
291 | * SH_CLK_DIV6_EXT() macro doesn't care .mapping | ||
292 | * but, it is necessary on R-Car (= ioremap() base CPG) | ||
293 | * The difference between | ||
294 | * SH_CLK_DIV6_EXT() <--> SH_CLK_MAP_DIV6_EXT() | ||
295 | * is only .mapping | ||
296 | */ | ||
297 | #define SH_CLK_MAP_DIV6_EXT(_reg, _flags, _parents, \ | ||
298 | _num_parents, _src_shift, _src_width) \ | ||
299 | { \ | ||
300 | .enable_reg = (void __iomem *)_reg, \ | ||
301 | .enable_bit = 0, /* unused */ \ | ||
302 | .flags = _flags | CLK_MASK_DIV_ON_DISABLE, \ | ||
303 | .div_mask = SH_CLK_DIV6_MSK, \ | ||
304 | .parent_table = _parents, \ | ||
305 | .parent_num = _num_parents, \ | ||
306 | .src_shift = _src_shift, \ | ||
307 | .src_width = _src_width, \ | ||
308 | .mapping = &cpg_mapping, \ | ||
309 | } | ||
310 | |||
311 | static struct clk div6_clks[DIV6_NR] = { | ||
312 | [DIV6_ZB] = SH_CLK_MAP_DIV6_EXT(ZBCKCR, CLK_ENABLE_ON_INIT, | ||
313 | div6_parents, 2, 7, 1), | ||
314 | [DIV6_SDHI0] = SH_CLK_MAP_DIV6_EXT(SD0CKCR, 0, | ||
315 | div6_parents, 2, 6, 2), | ||
316 | [DIV6_SDHI1] = SH_CLK_MAP_DIV6_EXT(SD1CKCR, 0, | ||
317 | div6_parents, 2, 6, 2), | ||
318 | [DIV6_SDHI2] = SH_CLK_MAP_DIV6_EXT(SD2CKCR, 0, | ||
319 | div6_parents, 2, 6, 2), | ||
320 | [DIV6_MMC0] = SH_CLK_MAP_DIV6_EXT(MMC0CKCR, 0, | ||
321 | div6_parents, 2, 6, 2), | ||
322 | [DIV6_MMC1] = SH_CLK_MAP_DIV6_EXT(MMC1CKCR, 0, | ||
323 | div6_parents, 2, 6, 2), | ||
324 | [DIV6_VCK1] = SH_CLK_MAP_DIV6_EXT(VCLKCR1, 0, /* didn't care bit[6-7] */ | ||
325 | div6_parents, ARRAY_SIZE(div6_parents), 12, 3), | ||
326 | [DIV6_VCK2] = SH_CLK_MAP_DIV6_EXT(VCLKCR2, 0, /* didn't care bit[6-7] */ | ||
327 | div6_parents, ARRAY_SIZE(div6_parents), 12, 3), | ||
328 | [DIV6_VCK3] = SH_CLK_MAP_DIV6_EXT(VCLKCR3, 0, /* didn't care bit[6-7] */ | ||
329 | div6_parents, ARRAY_SIZE(div6_parents), 12, 3), | ||
330 | [DIV6_VCK4] = SH_CLK_MAP_DIV6_EXT(VCLKCR4, 0, /* didn't care bit[6-7] */ | ||
331 | div6_parents, ARRAY_SIZE(div6_parents), 12, 3), | ||
332 | [DIV6_VCK5] = SH_CLK_MAP_DIV6_EXT(VCLKCR5, 0, /* didn't care bit[6-7] */ | ||
333 | div6_parents, ARRAY_SIZE(div6_parents), 12, 3), | ||
334 | [DIV6_FSIA] = SH_CLK_MAP_DIV6_EXT(FSIACKCR, 0, | ||
335 | fsia_parents, ARRAY_SIZE(fsia_parents), 6, 2), | ||
336 | [DIV6_FSIB] = SH_CLK_MAP_DIV6_EXT(FSIBCKCR, 0, | ||
337 | fsib_parents, ARRAY_SIZE(fsib_parents), 6, 2), | ||
338 | [DIV6_MP] = SH_CLK_MAP_DIV6_EXT(MPCKCR, 0, /* it needs bit[9-11] control */ | ||
339 | mp_parents, ARRAY_SIZE(mp_parents), 6, 2), | ||
340 | /* pll2s will be selected always for M4 */ | ||
341 | [DIV6_M4] = SH_CLK_MAP_DIV6_EXT(M4CKCR, 0, /* it needs bit[9] control */ | ||
342 | m4_parents, ARRAY_SIZE(m4_parents), 6, 1), | ||
343 | [DIV6_HSI] = SH_CLK_MAP_DIV6_EXT(HSICKCR, 0, /* it needs bit[9] control */ | ||
344 | hsi_parents, ARRAY_SIZE(hsi_parents), 6, 2), | ||
345 | [DIV6_SPUV] = SH_CLK_MAP_DIV6_EXT(SPUVCKCR, 0, | ||
346 | mp_parents, ARRAY_SIZE(mp_parents), 6, 2), | ||
347 | }; | ||
348 | |||
349 | /* MSTP */ | ||
350 | enum { | ||
61 | MSTP217, MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, | 351 | MSTP217, MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, |
352 | MSTP315, MSTP314, MSTP313, MSTP312, MSTP305, | ||
62 | MSTP522, | 353 | MSTP522, |
63 | MSTP_NR | 354 | MSTP_NR |
64 | }; | 355 | }; |
65 | 356 | ||
66 | static struct clk mstp_clks[MSTP_NR] = { | 357 | static struct clk mstp_clks[MSTP_NR] = { |
67 | [MSTP204] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR2, 4, 0), /* SCIFA0 */ | 358 | [MSTP204] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 4, 0), /* SCIFA0 */ |
68 | [MSTP203] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR2, 3, 0), /* SCIFA1 */ | 359 | [MSTP203] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 3, 0), /* SCIFA1 */ |
69 | [MSTP206] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR2, 6, 0), /* SCIFB0 */ | 360 | [MSTP206] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 6, 0), /* SCIFB0 */ |
70 | [MSTP207] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR2, 7, 0), /* SCIFB1 */ | 361 | [MSTP207] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 7, 0), /* SCIFB1 */ |
71 | [MSTP216] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR2, 16, 0), /* SCIFB2 */ | 362 | [MSTP216] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 16, 0), /* SCIFB2 */ |
72 | [MSTP217] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR2, 17, 0), /* SCIFB3 */ | 363 | [MSTP217] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 17, 0), /* SCIFB3 */ |
364 | [MSTP305] = SH_CLK_MSTP32(&div6_clks[DIV6_MMC1],SMSTPCR3, 5, 0), /* MMCIF1 */ | ||
365 | [MSTP312] = SH_CLK_MSTP32(&div6_clks[DIV6_SDHI2],SMSTPCR3, 12, 0), /* SDHI2 */ | ||
366 | [MSTP313] = SH_CLK_MSTP32(&div6_clks[DIV6_SDHI1],SMSTPCR3, 13, 0), /* SDHI1 */ | ||
367 | [MSTP314] = SH_CLK_MSTP32(&div6_clks[DIV6_SDHI0],SMSTPCR3, 14, 0), /* SDHI0 */ | ||
368 | [MSTP315] = SH_CLK_MSTP32(&div6_clks[DIV6_MMC0],SMSTPCR3, 15, 0), /* MMCIF0 */ | ||
73 | [MSTP522] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR5, 22, 0), /* Thermal */ | 369 | [MSTP522] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR5, 22, 0), /* Thermal */ |
74 | }; | 370 | }; |
75 | 371 | ||
76 | static struct clk_lookup lookups[] = { | 372 | static struct clk_lookup lookups[] = { |
373 | /* main clock */ | ||
374 | CLKDEV_CON_ID("extal1", &extal1_clk), | ||
375 | CLKDEV_CON_ID("extal1_div2", &extal1_div2_clk), | ||
376 | CLKDEV_CON_ID("extal2", &extal2_clk), | ||
377 | CLKDEV_CON_ID("extal2_div2", &extal2_div2_clk), | ||
378 | CLKDEV_CON_ID("extal2_div4", &extal2_div4_clk), | ||
379 | CLKDEV_CON_ID("fsiack", &fsiack_clk), | ||
380 | CLKDEV_CON_ID("fsibck", &fsibck_clk), | ||
381 | |||
382 | /* pll clock */ | ||
383 | CLKDEV_CON_ID("pll1", &pll1_clk), | ||
384 | CLKDEV_CON_ID("pll1_div2", &pll1_div2_clk), | ||
385 | CLKDEV_CON_ID("pll2", &pll2_clk), | ||
386 | CLKDEV_CON_ID("pll2s", &pll2s_clk), | ||
387 | CLKDEV_CON_ID("pll2h", &pll2h_clk), | ||
388 | |||
389 | /* DIV6 */ | ||
390 | CLKDEV_CON_ID("zb", &div6_clks[DIV6_ZB]), | ||
391 | CLKDEV_CON_ID("vck1", &div6_clks[DIV6_VCK1]), | ||
392 | CLKDEV_CON_ID("vck2", &div6_clks[DIV6_VCK2]), | ||
393 | CLKDEV_CON_ID("vck3", &div6_clks[DIV6_VCK3]), | ||
394 | CLKDEV_CON_ID("vck4", &div6_clks[DIV6_VCK4]), | ||
395 | CLKDEV_CON_ID("vck5", &div6_clks[DIV6_VCK5]), | ||
396 | CLKDEV_CON_ID("fsia", &div6_clks[DIV6_FSIA]), | ||
397 | CLKDEV_CON_ID("fsib", &div6_clks[DIV6_FSIB]), | ||
398 | CLKDEV_CON_ID("mp", &div6_clks[DIV6_MP]), | ||
399 | CLKDEV_CON_ID("m4", &div6_clks[DIV6_M4]), | ||
400 | CLKDEV_CON_ID("hsi", &div6_clks[DIV6_HSI]), | ||
401 | CLKDEV_CON_ID("spuv", &div6_clks[DIV6_SPUV]), | ||
402 | |||
403 | /* MSTP */ | ||
77 | CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), | 404 | CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), |
78 | CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), | 405 | CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), |
79 | CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP206]), | 406 | CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP206]), |
@@ -81,6 +408,16 @@ static struct clk_lookup lookups[] = { | |||
81 | CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP216]), | 408 | CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP216]), |
82 | CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP217]), | 409 | CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP217]), |
83 | CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]), | 410 | CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]), |
411 | CLKDEV_DEV_ID("sh_mmcif.1", &mstp_clks[MSTP305]), | ||
412 | CLKDEV_DEV_ID("ee220000.mmcif", &mstp_clks[MSTP305]), | ||
413 | CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP312]), | ||
414 | CLKDEV_DEV_ID("ee140000.sdhi", &mstp_clks[MSTP312]), | ||
415 | CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), | ||
416 | CLKDEV_DEV_ID("ee120000.sdhi", &mstp_clks[MSTP313]), | ||
417 | CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), | ||
418 | CLKDEV_DEV_ID("ee100000.sdhi", &mstp_clks[MSTP314]), | ||
419 | CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP315]), | ||
420 | CLKDEV_DEV_ID("ee200000.mmcif", &mstp_clks[MSTP315]), | ||
84 | 421 | ||
85 | /* for DT */ | 422 | /* for DT */ |
86 | CLKDEV_DEV_ID("e61f0000.thermal", &mstp_clks[MSTP522]), | 423 | CLKDEV_DEV_ID("e61f0000.thermal", &mstp_clks[MSTP522]), |
@@ -88,22 +425,40 @@ static struct clk_lookup lookups[] = { | |||
88 | 425 | ||
89 | void __init r8a73a4_clock_init(void) | 426 | void __init r8a73a4_clock_init(void) |
90 | { | 427 | { |
91 | void __iomem *cpg_base, *reg; | 428 | void __iomem *reg; |
92 | int k, ret = 0; | 429 | int k, ret = 0; |
430 | u32 ckscr; | ||
431 | |||
432 | reg = ioremap_nocache(CKSCR, PAGE_SIZE); | ||
433 | BUG_ON(!reg); | ||
434 | ckscr = ioread32(reg); | ||
435 | iounmap(reg); | ||
93 | 436 | ||
94 | /* fix MPCLK to EXTAL2 for now. | 437 | switch ((ckscr >> 28) & 0x3) { |
95 | * this is needed until more detailed clock topology is supported | 438 | case 0: |
96 | */ | 439 | main_clk.parent = &extal1_clk; |
97 | cpg_base = ioremap_nocache(CPG_BASE, CPG_LEN); | 440 | break; |
98 | BUG_ON(!cpg_base); | 441 | case 1: |
99 | reg = cpg_base + (MPCKCR - CPG_BASE); | 442 | main_clk.parent = &extal1_div2_clk; |
100 | iowrite32(ioread32(reg) | 1 << 7 | 0x0c, reg); /* set CKSEL */ | 443 | break; |
101 | iounmap(cpg_base); | 444 | case 2: |
445 | main_clk.parent = &extal2_clk; | ||
446 | break; | ||
447 | case 3: | ||
448 | main_clk.parent = &extal2_div2_clk; | ||
449 | break; | ||
450 | } | ||
102 | 451 | ||
103 | for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) | 452 | for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) |
104 | ret = clk_register(main_clks[k]); | 453 | ret = clk_register(main_clks[k]); |
105 | 454 | ||
106 | if (!ret) | 455 | if (!ret) |
456 | ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); | ||
457 | |||
458 | if (!ret) | ||
459 | ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR); | ||
460 | |||
461 | if (!ret) | ||
107 | ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); | 462 | ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); |
108 | 463 | ||
109 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); | 464 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); |