aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-shmobile
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-shmobile')
-rw-r--r--arch/arm/mach-shmobile/Kconfig4
-rw-r--r--arch/arm/mach-shmobile/board-ape6evm.c1
-rw-r--r--arch/arm/mach-shmobile/board-lager.c1
-rw-r--r--arch/arm/mach-shmobile/clock-emev2.c18
-rw-r--r--arch/arm/mach-shmobile/clock-r8a73a4.c199
-rw-r--r--arch/arm/mach-shmobile/clock-r8a7740.c1
-rw-r--r--arch/arm/mach-shmobile/clock-r8a7790.c27
-rw-r--r--arch/arm/mach-shmobile/include/mach/emev2.h1
-rw-r--r--arch/arm/mach-shmobile/include/mach/r8a73a4.h1
-rw-r--r--arch/arm/mach-shmobile/include/mach/r8a7740.h2
-rw-r--r--arch/arm/mach-shmobile/include/mach/r8a7790.h4
-rw-r--r--arch/arm/mach-shmobile/setup-r8a73a4.c30
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7740.c10
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7790.c106
-rw-r--r--arch/arm/mach-shmobile/smp-emev2.c11
15 files changed, 368 insertions, 48 deletions
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index cdefd7dcca79..403c939ddf99 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -61,9 +61,10 @@ config ARCH_R8A73A4
61 select ARCH_WANT_OPTIONAL_GPIOLIB 61 select ARCH_WANT_OPTIONAL_GPIOLIB
62 select ARM_GIC 62 select ARM_GIC
63 select CPU_V7 63 select CPU_V7
64 select HAVE_ARM_ARCH_TIMER
65 select SH_CLK_CPG 64 select SH_CLK_CPG
66 select RENESAS_IRQC 65 select RENESAS_IRQC
66 select ARCH_HAS_CPUFREQ
67 select ARCH_HAS_OPP
67 68
68config ARCH_R8A7740 69config ARCH_R8A7740
69 bool "R-Mobile A1 (R8A77400)" 70 bool "R-Mobile A1 (R8A77400)"
@@ -97,7 +98,6 @@ config ARCH_R8A7790
97 select ARCH_WANT_OPTIONAL_GPIOLIB 98 select ARCH_WANT_OPTIONAL_GPIOLIB
98 select ARM_GIC 99 select ARM_GIC
99 select CPU_V7 100 select CPU_V7
100 select HAVE_ARM_ARCH_TIMER
101 select SH_CLK_CPG 101 select SH_CLK_CPG
102 select RENESAS_IRQC 102 select RENESAS_IRQC
103 103
diff --git a/arch/arm/mach-shmobile/board-ape6evm.c b/arch/arm/mach-shmobile/board-ape6evm.c
index 1fbc39a14e25..af6dd39d3758 100644
--- a/arch/arm/mach-shmobile/board-ape6evm.c
+++ b/arch/arm/mach-shmobile/board-ape6evm.c
@@ -101,6 +101,7 @@ static const char *ape6evm_boards_compat_dt[] __initdata = {
101}; 101};
102 102
103DT_MACHINE_START(APE6EVM_DT, "ape6evm") 103DT_MACHINE_START(APE6EVM_DT, "ape6evm")
104 .init_early = r8a73a4_init_delay,
104 .init_time = shmobile_timer_init, 105 .init_time = shmobile_timer_init,
105 .init_machine = ape6evm_add_standard_devices, 106 .init_machine = ape6evm_add_standard_devices,
106 .dt_compat = ape6evm_boards_compat_dt, 107 .dt_compat = ape6evm_boards_compat_dt,
diff --git a/arch/arm/mach-shmobile/board-lager.c b/arch/arm/mach-shmobile/board-lager.c
index 78d92d34665d..f89f16650731 100644
--- a/arch/arm/mach-shmobile/board-lager.c
+++ b/arch/arm/mach-shmobile/board-lager.c
@@ -102,6 +102,7 @@ static const char *lager_boards_compat_dt[] __initdata = {
102}; 102};
103 103
104DT_MACHINE_START(LAGER_DT, "lager") 104DT_MACHINE_START(LAGER_DT, "lager")
105 .init_early = r8a7790_init_delay,
105 .init_time = r8a7790_timer_init, 106 .init_time = r8a7790_timer_init,
106 .init_machine = lager_add_standard_devices, 107 .init_machine = lager_add_standard_devices,
107 .dt_compat = lager_boards_compat_dt, 108 .dt_compat = lager_boards_compat_dt,
diff --git a/arch/arm/mach-shmobile/clock-emev2.c b/arch/arm/mach-shmobile/clock-emev2.c
index 56dd0cfcddc7..5ac13ba71d54 100644
--- a/arch/arm/mach-shmobile/clock-emev2.c
+++ b/arch/arm/mach-shmobile/clock-emev2.c
@@ -40,7 +40,6 @@
40#define USIB2SCLKDIV 0x65c 40#define USIB2SCLKDIV 0x65c
41#define USIB3SCLKDIV 0x660 41#define USIB3SCLKDIV 0x660
42#define STI_CLKSEL 0x688 42#define STI_CLKSEL 0x688
43#define SMU_GENERAL_REG0 0x7c0
44 43
45/* not pretty, but hey */ 44/* not pretty, but hey */
46static void __iomem *smu_base; 45static void __iomem *smu_base;
@@ -51,11 +50,6 @@ static void emev2_smu_write(unsigned long value, int offs)
51 iowrite32(value, smu_base + offs); 50 iowrite32(value, smu_base + offs);
52} 51}
53 52
54void emev2_set_boot_vector(unsigned long value)
55{
56 emev2_smu_write(value, SMU_GENERAL_REG0);
57}
58
59static struct clk_mapping smu_mapping = { 53static struct clk_mapping smu_mapping = {
60 .phys = EMEV2_SMU_BASE, 54 .phys = EMEV2_SMU_BASE,
61 .len = PAGE_SIZE, 55 .len = PAGE_SIZE,
@@ -205,18 +199,6 @@ static struct clk_lookup lookups[] = {
205void __init emev2_clock_init(void) 199void __init emev2_clock_init(void)
206{ 200{
207 int k, ret = 0; 201 int k, ret = 0;
208 static int is_setup;
209
210 /* yuck, this is ugly as hell, but the non-smp case of clocks
211 * code is now designed to rely on ioremap() instead of static
212 * entity maps. in the case of smp we need access to the SMU
213 * register earlier than ioremap() is actually working without
214 * any static maps. to enable SMP in ugly but with dynamic
215 * mappings we have to call emev2_clock_init() from different
216 * places depending on UP and SMP...
217 */
218 if (is_setup++)
219 return;
220 202
221 smu_base = ioremap(EMEV2_SMU_BASE, PAGE_SIZE); 203 smu_base = ioremap(EMEV2_SMU_BASE, PAGE_SIZE);
222 BUG_ON(!smu_base); 204 BUG_ON(!smu_base);
diff --git a/arch/arm/mach-shmobile/clock-r8a73a4.c b/arch/arm/mach-shmobile/clock-r8a73a4.c
index 5f7fe628b8a1..8ea5ef6c79cc 100644
--- a/arch/arm/mach-shmobile/clock-r8a73a4.c
+++ b/arch/arm/mach-shmobile/clock-r8a73a4.c
@@ -30,10 +30,12 @@
30 30
31#define SMSTPCR2 0xe6150138 31#define SMSTPCR2 0xe6150138
32#define SMSTPCR3 0xe615013c 32#define SMSTPCR3 0xe615013c
33#define SMSTPCR4 0xe6150140
33#define SMSTPCR5 0xe6150144 34#define SMSTPCR5 0xe6150144
34 35
35#define FRQCRA 0xE6150000 36#define FRQCRA 0xE6150000
36#define FRQCRB 0xE6150004 37#define FRQCRB 0xE6150004
38#define FRQCRC 0xE61500E0
37#define VCLKCR1 0xE6150008 39#define VCLKCR1 0xE6150008
38#define VCLKCR2 0xE615000C 40#define VCLKCR2 0xE615000C
39#define VCLKCR3 0xE615001C 41#define VCLKCR3 0xE615001C
@@ -52,6 +54,7 @@
52#define HSICKCR 0xE615026C 54#define HSICKCR 0xE615026C
53#define M4CKCR 0xE6150098 55#define M4CKCR 0xE6150098
54#define PLLECR 0xE61500D0 56#define PLLECR 0xE61500D0
57#define PLL0CR 0xE61500D8
55#define PLL1CR 0xE6150028 58#define PLL1CR 0xE6150028
56#define PLL2CR 0xE615002C 59#define PLL2CR 0xE615002C
57#define PLL2SCR 0xE61501F4 60#define PLL2SCR 0xE61501F4
@@ -177,6 +180,7 @@ static struct sh_clk_ops pll_clk_ops = {
177 .mapping = &cpg_mapping, \ 180 .mapping = &cpg_mapping, \
178 } 181 }
179 182
183PLL_CLOCK(pll0_clk, &main_clk, pll_parent_main, 1, 20, PLL0CR, 0);
180PLL_CLOCK(pll1_clk, &main_clk, pll_parent_main, 1, 7, PLL1CR, 1); 184PLL_CLOCK(pll1_clk, &main_clk, pll_parent_main, 1, 7, PLL1CR, 1);
181PLL_CLOCK(pll2_clk, &main_div2_clk, pll_parent_main_extal, 3, 5, PLL2CR, 2); 185PLL_CLOCK(pll2_clk, &main_div2_clk, pll_parent_main_extal, 3, 5, PLL2CR, 2);
182PLL_CLOCK(pll2s_clk, &main_div2_clk, pll_parent_main_extal, 3, 5, PLL2SCR, 4); 186PLL_CLOCK(pll2s_clk, &main_div2_clk, pll_parent_main_extal, 3, 5, PLL2SCR, 4);
@@ -184,6 +188,157 @@ PLL_CLOCK(pll2h_clk, &main_div2_clk, pll_parent_main_extal, 3, 5, PLL2HCR, 5);
184 188
185SH_FIXED_RATIO_CLK(pll1_div2_clk, pll1_clk, div2); 189SH_FIXED_RATIO_CLK(pll1_div2_clk, pll1_clk, div2);
186 190
191static atomic_t frqcr_lock;
192
193/* Several clocks need to access FRQCRB, have to lock */
194static bool frqcr_kick_check(struct clk *clk)
195{
196 return !(ioread32(CPG_MAP(FRQCRB)) & BIT(31));
197}
198
199static int frqcr_kick_do(struct clk *clk)
200{
201 int i;
202
203 /* set KICK bit in FRQCRB to update hardware setting, check success */
204 iowrite32(ioread32(CPG_MAP(FRQCRB)) | BIT(31), CPG_MAP(FRQCRB));
205 for (i = 1000; i; i--)
206 if (ioread32(CPG_MAP(FRQCRB)) & BIT(31))
207 cpu_relax();
208 else
209 return 0;
210
211 return -ETIMEDOUT;
212}
213
214static int zclk_set_rate(struct clk *clk, unsigned long rate)
215{
216 void __iomem *frqcrc;
217 int ret;
218 unsigned long step, p_rate;
219 u32 val;
220
221 if (!clk->parent || !__clk_get(clk->parent))
222 return -ENODEV;
223
224 if (!atomic_inc_and_test(&frqcr_lock) || !frqcr_kick_check(clk)) {
225 ret = -EBUSY;
226 goto done;
227 }
228
229 /*
230 * Users are supposed to first call clk_set_rate() only with
231 * clk_round_rate() results. So, we don't fix wrong rates here, but
232 * guard against them anyway
233 */
234
235 p_rate = clk_get_rate(clk->parent);
236 if (rate == p_rate) {
237 val = 0;
238 } else {
239 step = DIV_ROUND_CLOSEST(p_rate, 32);
240
241 if (rate > p_rate || rate < step) {
242 ret = -EINVAL;
243 goto done;
244 }
245
246 val = 32 - rate / step;
247 }
248
249 frqcrc = clk->mapped_reg + (FRQCRC - (u32)clk->enable_reg);
250
251 iowrite32((ioread32(frqcrc) & ~(clk->div_mask << clk->enable_bit)) |
252 (val << clk->enable_bit), frqcrc);
253
254 ret = frqcr_kick_do(clk);
255
256done:
257 atomic_dec(&frqcr_lock);
258 __clk_put(clk->parent);
259 return ret;
260}
261
262static long zclk_round_rate(struct clk *clk, unsigned long rate)
263{
264 /*
265 * theoretical rate = parent rate * multiplier / 32,
266 * where 1 <= multiplier <= 32. Therefore we should do
267 * multiplier = rate * 32 / parent rate
268 * rounded rate = parent rate * multiplier / 32.
269 * However, multiplication before division won't fit in 32 bits, so
270 * we sacrifice some precision by first dividing and then multiplying.
271 * To find the nearest divisor we calculate both and pick up the best
272 * one. This avoids 64-bit arithmetics.
273 */
274 unsigned long step, mul_min, mul_max, rate_min, rate_max;
275
276 rate_max = clk_get_rate(clk->parent);
277
278 /* output freq <= parent */
279 if (rate >= rate_max)
280 return rate_max;
281
282 step = DIV_ROUND_CLOSEST(rate_max, 32);
283 /* output freq >= parent / 32 */
284 if (step >= rate)
285 return step;
286
287 mul_min = rate / step;
288 mul_max = DIV_ROUND_UP(rate, step);
289 rate_min = step * mul_min;
290 if (mul_max == mul_min)
291 return rate_min;
292
293 rate_max = step * mul_max;
294
295 if (rate_max - rate < rate - rate_min)
296 return rate_max;
297
298 return rate_min;
299}
300
301static unsigned long zclk_recalc(struct clk *clk)
302{
303 void __iomem *frqcrc = FRQCRC - (u32)clk->enable_reg + clk->mapped_reg;
304 unsigned int max = clk->div_mask + 1;
305 unsigned long val = ((ioread32(frqcrc) >> clk->enable_bit) &
306 clk->div_mask);
307
308 return DIV_ROUND_CLOSEST(clk_get_rate(clk->parent), max) *
309 (max - val);
310}
311
312static struct sh_clk_ops zclk_ops = {
313 .recalc = zclk_recalc,
314 .set_rate = zclk_set_rate,
315 .round_rate = zclk_round_rate,
316};
317
318static struct clk z_clk = {
319 .parent = &pll0_clk,
320 .div_mask = 0x1f,
321 .enable_bit = 8,
322 /* We'll need to access FRQCRB and FRQCRC */
323 .enable_reg = (void __iomem *)FRQCRB,
324 .ops = &zclk_ops,
325};
326
327/*
328 * It seems only 1/2 divider is usable in manual mode. 1/2 / 2/3
329 * switching is only available in auto-DVFS mode
330 */
331SH_FIXED_RATIO_CLK(pll0_div2_clk, pll0_clk, div2);
332
333static struct clk z2_clk = {
334 .parent = &pll0_div2_clk,
335 .div_mask = 0x1f,
336 .enable_bit = 0,
337 /* We'll need to access FRQCRB and FRQCRC */
338 .enable_reg = (void __iomem *)FRQCRB,
339 .ops = &zclk_ops,
340};
341
187static struct clk *main_clks[] = { 342static struct clk *main_clks[] = {
188 &extalr_clk, 343 &extalr_clk,
189 &extal1_clk, 344 &extal1_clk,
@@ -195,22 +350,23 @@ static struct clk *main_clks[] = {
195 &main_div2_clk, 350 &main_div2_clk,
196 &fsiack_clk, 351 &fsiack_clk,
197 &fsibck_clk, 352 &fsibck_clk,
353 &pll0_clk,
198 &pll1_clk, 354 &pll1_clk,
199 &pll1_div2_clk, 355 &pll1_div2_clk,
200 &pll2_clk, 356 &pll2_clk,
201 &pll2s_clk, 357 &pll2s_clk,
202 &pll2h_clk, 358 &pll2h_clk,
359 &z_clk,
360 &pll0_div2_clk,
361 &z2_clk,
203}; 362};
204 363
205/* DIV4 */ 364/* DIV4 */
206static void div4_kick(struct clk *clk) 365static void div4_kick(struct clk *clk)
207{ 366{
208 unsigned long value; 367 if (!WARN(!atomic_inc_and_test(&frqcr_lock), "FRQCR* lock broken!\n"))
209 368 frqcr_kick_do(clk);
210 /* set KICK bit in FRQCRB to update hardware setting */ 369 atomic_dec(&frqcr_lock);
211 value = ioread32(CPG_MAP(FRQCRB));
212 value |= (1 << 31);
213 iowrite32(value, CPG_MAP(FRQCRB));
214} 370}
215 371
216static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18, 24, 0, 36, 48, 10}; 372static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18, 24, 0, 36, 48, 10};
@@ -349,8 +505,10 @@ static struct clk div6_clks[DIV6_NR] = {
349/* MSTP */ 505/* MSTP */
350enum { 506enum {
351 MSTP217, MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, 507 MSTP217, MSTP216, MSTP207, MSTP206, MSTP204, MSTP203,
352 MSTP315, MSTP314, MSTP313, MSTP312, MSTP305, 508 MSTP329, MSTP323, MSTP318, MSTP317, MSTP316,
353 MSTP522, 509 MSTP315, MSTP314, MSTP313, MSTP312, MSTP305, MSTP300,
510 MSTP411, MSTP410, MSTP409,
511 MSTP522, MSTP515,
354 MSTP_NR 512 MSTP_NR
355}; 513};
356 514
@@ -361,12 +519,22 @@ static struct clk mstp_clks[MSTP_NR] = {
361 [MSTP207] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 7, 0), /* SCIFB1 */ 519 [MSTP207] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 7, 0), /* SCIFB1 */
362 [MSTP216] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 16, 0), /* SCIFB2 */ 520 [MSTP216] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 16, 0), /* SCIFB2 */
363 [MSTP217] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 17, 0), /* SCIFB3 */ 521 [MSTP217] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 17, 0), /* SCIFB3 */
522 [MSTP300] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 0, 0), /* IIC2 */
364 [MSTP305] = SH_CLK_MSTP32(&div6_clks[DIV6_MMC1],SMSTPCR3, 5, 0), /* MMCIF1 */ 523 [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 */ 524 [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 */ 525 [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 */ 526 [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 */ 527 [MSTP315] = SH_CLK_MSTP32(&div6_clks[DIV6_MMC0],SMSTPCR3, 15, 0), /* MMCIF0 */
528 [MSTP316] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 16, 0), /* IIC6 */
529 [MSTP317] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 17, 0), /* IIC7 */
530 [MSTP318] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 18, 0), /* IIC0 */
531 [MSTP323] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 23, 0), /* IIC1 */
532 [MSTP329] = SH_CLK_MSTP32(&extalr_clk, SMSTPCR3, 29, 0), /* CMT10 */
533 [MSTP409] = SH_CLK_MSTP32(&main_div2_clk, SMSTPCR4, 9, 0), /* IIC5 */
534 [MSTP410] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR4, 10, 0), /* IIC4 */
535 [MSTP411] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR4, 11, 0), /* IIC3 */
369 [MSTP522] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR5, 22, 0), /* Thermal */ 536 [MSTP522] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR5, 22, 0), /* Thermal */
537 [MSTP515] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR5, 15, 0), /* IIC8 */
370}; 538};
371 539
372static struct clk_lookup lookups[] = { 540static struct clk_lookup lookups[] = {
@@ -386,6 +554,9 @@ static struct clk_lookup lookups[] = {
386 CLKDEV_CON_ID("pll2s", &pll2s_clk), 554 CLKDEV_CON_ID("pll2s", &pll2s_clk),
387 CLKDEV_CON_ID("pll2h", &pll2h_clk), 555 CLKDEV_CON_ID("pll2h", &pll2h_clk),
388 556
557 /* CPU clock */
558 CLKDEV_DEV_ID("cpufreq-cpu0", &z_clk),
559
389 /* DIV6 */ 560 /* DIV6 */
390 CLKDEV_CON_ID("zb", &div6_clks[DIV6_ZB]), 561 CLKDEV_CON_ID("zb", &div6_clks[DIV6_ZB]),
391 CLKDEV_CON_ID("vck1", &div6_clks[DIV6_VCK1]), 562 CLKDEV_CON_ID("vck1", &div6_clks[DIV6_VCK1]),
@@ -408,6 +579,7 @@ static struct clk_lookup lookups[] = {
408 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP216]), 579 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP216]),
409 CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP217]), 580 CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP217]),
410 CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]), 581 CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]),
582 CLKDEV_DEV_ID("e6520000.i2c", &mstp_clks[MSTP300]),
411 CLKDEV_DEV_ID("sh_mmcif.1", &mstp_clks[MSTP305]), 583 CLKDEV_DEV_ID("sh_mmcif.1", &mstp_clks[MSTP305]),
412 CLKDEV_DEV_ID("ee220000.mmcif", &mstp_clks[MSTP305]), 584 CLKDEV_DEV_ID("ee220000.mmcif", &mstp_clks[MSTP305]),
413 CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP312]), 585 CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP312]),
@@ -418,6 +590,15 @@ static struct clk_lookup lookups[] = {
418 CLKDEV_DEV_ID("ee100000.sdhi", &mstp_clks[MSTP314]), 590 CLKDEV_DEV_ID("ee100000.sdhi", &mstp_clks[MSTP314]),
419 CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP315]), 591 CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP315]),
420 CLKDEV_DEV_ID("ee200000.mmcif", &mstp_clks[MSTP315]), 592 CLKDEV_DEV_ID("ee200000.mmcif", &mstp_clks[MSTP315]),
593 CLKDEV_DEV_ID("e6550000.i2c", &mstp_clks[MSTP316]),
594 CLKDEV_DEV_ID("e6560000.i2c", &mstp_clks[MSTP317]),
595 CLKDEV_DEV_ID("e6500000.i2c", &mstp_clks[MSTP318]),
596 CLKDEV_DEV_ID("e6510000.i2c", &mstp_clks[MSTP323]),
597 CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]),
598 CLKDEV_DEV_ID("e60b0000.i2c", &mstp_clks[MSTP409]),
599 CLKDEV_DEV_ID("e6540000.i2c", &mstp_clks[MSTP410]),
600 CLKDEV_DEV_ID("e6530000.i2c", &mstp_clks[MSTP411]),
601 CLKDEV_DEV_ID("e6570000.i2c", &mstp_clks[MSTP515]),
421 602
422 /* for DT */ 603 /* for DT */
423 CLKDEV_DEV_ID("e61f0000.thermal", &mstp_clks[MSTP522]), 604 CLKDEV_DEV_ID("e61f0000.thermal", &mstp_clks[MSTP522]),
@@ -429,6 +610,8 @@ void __init r8a73a4_clock_init(void)
429 int k, ret = 0; 610 int k, ret = 0;
430 u32 ckscr; 611 u32 ckscr;
431 612
613 atomic_set(&frqcr_lock, -1);
614
432 reg = ioremap_nocache(CKSCR, PAGE_SIZE); 615 reg = ioremap_nocache(CKSCR, PAGE_SIZE);
433 BUG_ON(!reg); 616 BUG_ON(!reg);
434 ckscr = ioread32(reg); 617 ckscr = ioread32(reg);
diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c
index f4265e52432c..c826bca4024e 100644
--- a/arch/arm/mach-shmobile/clock-r8a7740.c
+++ b/arch/arm/mach-shmobile/clock-r8a7740.c
@@ -597,6 +597,7 @@ static struct clk_lookup lookups[] = {
597 CLKDEV_DEV_ID("r8a7740-gether", &mstp_clks[MSTP309]), 597 CLKDEV_DEV_ID("r8a7740-gether", &mstp_clks[MSTP309]),
598 CLKDEV_DEV_ID("e9a00000.sh-eth", &mstp_clks[MSTP309]), 598 CLKDEV_DEV_ID("e9a00000.sh-eth", &mstp_clks[MSTP309]),
599 CLKDEV_DEV_ID("renesas-tpu-pwm", &mstp_clks[MSTP304]), 599 CLKDEV_DEV_ID("renesas-tpu-pwm", &mstp_clks[MSTP304]),
600 CLKDEV_DEV_ID("e6600000.pwm", &mstp_clks[MSTP304]),
600 601
601 CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]), 602 CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]),
602 CLKDEV_DEV_ID("e6870000.sdhi", &mstp_clks[MSTP415]), 603 CLKDEV_DEV_ID("e6870000.sdhi", &mstp_clks[MSTP415]),
diff --git a/arch/arm/mach-shmobile/clock-r8a7790.c b/arch/arm/mach-shmobile/clock-r8a7790.c
index 5d71313df52d..fc36d3db0b4d 100644
--- a/arch/arm/mach-shmobile/clock-r8a7790.c
+++ b/arch/arm/mach-shmobile/clock-r8a7790.c
@@ -24,6 +24,7 @@
24#include <linux/clkdev.h> 24#include <linux/clkdev.h>
25#include <mach/clock.h> 25#include <mach/clock.h>
26#include <mach/common.h> 26#include <mach/common.h>
27#include <mach/r8a7790.h>
27 28
28/* 29/*
29 * MD EXTAL PLL0 PLL1 PLL3 30 * MD EXTAL PLL0 PLL1 PLL3
@@ -42,16 +43,16 @@
42 * see "p1 / 2" on R8A7790_CLOCK_ROOT() below 43 * see "p1 / 2" on R8A7790_CLOCK_ROOT() below
43 */ 44 */
44 45
45#define MD(nr) (1 << nr)
46
47#define CPG_BASE 0xe6150000 46#define CPG_BASE 0xe6150000
48#define CPG_LEN 0x1000 47#define CPG_LEN 0x1000
49 48
49#define SMSTPCR1 0xe6150134
50#define SMSTPCR2 0xe6150138 50#define SMSTPCR2 0xe6150138
51#define SMSTPCR3 0xe615013c 51#define SMSTPCR3 0xe615013c
52#define SMSTPCR5 0xe6150144
52#define SMSTPCR7 0xe615014c 53#define SMSTPCR7 0xe615014c
54#define SMSTPCR8 0xe6150990
53 55
54#define MODEMR 0xE6160060
55#define SDCKCR 0xE6150074 56#define SDCKCR 0xE6150074
56#define SD2CKCR 0xE6150078 57#define SD2CKCR 0xE6150078
57#define SD3CKCR 0xE615007C 58#define SD3CKCR 0xE615007C
@@ -180,16 +181,23 @@ static struct clk div6_clks[DIV6_NR] = {
180 181
181/* MSTP */ 182/* MSTP */
182enum { 183enum {
184 MSTP813,
183 MSTP721, MSTP720, 185 MSTP721, MSTP720,
184 MSTP717, MSTP716, 186 MSTP717, MSTP716,
187 MSTP522,
185 MSTP315, MSTP314, MSTP313, MSTP312, MSTP311, MSTP305, MSTP304, 188 MSTP315, MSTP314, MSTP313, MSTP312, MSTP311, MSTP305, MSTP304,
186 MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, 189 MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202,
190 MSTP124,
187 MSTP_NR 191 MSTP_NR
188}; 192};
189 193
190static struct clk mstp_clks[MSTP_NR] = { 194static struct clk mstp_clks[MSTP_NR] = {
195 [MSTP813] = SH_CLK_MSTP32(&p_clk, SMSTPCR8, 13, 0), /* Ether */
191 [MSTP721] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 21, 0), /* SCIF0 */ 196 [MSTP721] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 21, 0), /* SCIF0 */
192 [MSTP720] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 20, 0), /* SCIF1 */ 197 [MSTP720] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 20, 0), /* SCIF1 */
198 [MSTP717] = SH_CLK_MSTP32(&zs_clk, SMSTPCR7, 17, 0), /* HSCIF0 */
199 [MSTP716] = SH_CLK_MSTP32(&zs_clk, SMSTPCR7, 16, 0), /* HSCIF1 */
200 [MSTP522] = SH_CLK_MSTP32(&extal_clk, SMSTPCR5, 22, 0), /* Thermal */
193 [MSTP315] = SH_CLK_MSTP32(&div6_clks[DIV6_MMC0], SMSTPCR3, 15, 0), /* MMC0 */ 201 [MSTP315] = SH_CLK_MSTP32(&div6_clks[DIV6_MMC0], SMSTPCR3, 15, 0), /* MMC0 */
194 [MSTP314] = SH_CLK_MSTP32(&div4_clks[DIV4_SD0], SMSTPCR3, 14, 0), /* SDHI0 */ 202 [MSTP314] = SH_CLK_MSTP32(&div4_clks[DIV4_SD0], SMSTPCR3, 14, 0), /* SDHI0 */
195 [MSTP313] = SH_CLK_MSTP32(&div4_clks[DIV4_SD1], SMSTPCR3, 13, 0), /* SDHI1 */ 203 [MSTP313] = SH_CLK_MSTP32(&div4_clks[DIV4_SD1], SMSTPCR3, 13, 0), /* SDHI1 */
@@ -203,8 +211,7 @@ static struct clk mstp_clks[MSTP_NR] = {
203 [MSTP204] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 4, 0), /* SCIFA0 */ 211 [MSTP204] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 4, 0), /* SCIFA0 */
204 [MSTP203] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 3, 0), /* SCIFA1 */ 212 [MSTP203] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 3, 0), /* SCIFA1 */
205 [MSTP202] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 2, 0), /* SCIFA2 */ 213 [MSTP202] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 2, 0), /* SCIFA2 */
206 [MSTP717] = SH_CLK_MSTP32(&zs_clk, SMSTPCR7, 17, 0), /* HSCIF0 */ 214 [MSTP124] = SH_CLK_MSTP32(&rclk_clk, SMSTPCR1, 24, 0), /* CMT0 */
207 [MSTP716] = SH_CLK_MSTP32(&zs_clk, SMSTPCR7, 16, 0), /* HSCIF1 */
208}; 215};
209 216
210static struct clk_lookup lookups[] = { 217static struct clk_lookup lookups[] = {
@@ -254,6 +261,8 @@ static struct clk_lookup lookups[] = {
254 CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP720]), 261 CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP720]),
255 CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP717]), 262 CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP717]),
256 CLKDEV_DEV_ID("sh-sci.9", &mstp_clks[MSTP716]), 263 CLKDEV_DEV_ID("sh-sci.9", &mstp_clks[MSTP716]),
264 CLKDEV_DEV_ID("r8a7790-ether", &mstp_clks[MSTP813]),
265 CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]),
257 CLKDEV_DEV_ID("ee200000.mmcif", &mstp_clks[MSTP315]), 266 CLKDEV_DEV_ID("ee200000.mmcif", &mstp_clks[MSTP315]),
258 CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP315]), 267 CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP315]),
259 CLKDEV_DEV_ID("ee100000.sdhi", &mstp_clks[MSTP314]), 268 CLKDEV_DEV_ID("ee100000.sdhi", &mstp_clks[MSTP314]),
@@ -266,6 +275,7 @@ static struct clk_lookup lookups[] = {
266 CLKDEV_DEV_ID("sh_mobile_sdhi.3", &mstp_clks[MSTP311]), 275 CLKDEV_DEV_ID("sh_mobile_sdhi.3", &mstp_clks[MSTP311]),
267 CLKDEV_DEV_ID("ee220000.mmcif", &mstp_clks[MSTP305]), 276 CLKDEV_DEV_ID("ee220000.mmcif", &mstp_clks[MSTP305]),
268 CLKDEV_DEV_ID("sh_mmcif.1", &mstp_clks[MSTP305]), 277 CLKDEV_DEV_ID("sh_mmcif.1", &mstp_clks[MSTP305]),
278 CLKDEV_DEV_ID("sh_cmt.0", &mstp_clks[MSTP124]),
269}; 279};
270 280
271#define R8A7790_CLOCK_ROOT(e, m, p0, p1, p30, p31) \ 281#define R8A7790_CLOCK_ROOT(e, m, p0, p1, p30, p31) \
@@ -280,14 +290,9 @@ static struct clk_lookup lookups[] = {
280 290
281void __init r8a7790_clock_init(void) 291void __init r8a7790_clock_init(void)
282{ 292{
283 void __iomem *modemr = ioremap_nocache(MODEMR, PAGE_SIZE); 293 u32 mode = r8a7790_read_mode_pins();
284 u32 mode;
285 int k, ret = 0; 294 int k, ret = 0;
286 295
287 BUG_ON(!modemr);
288 mode = ioread32(modemr);
289 iounmap(modemr);
290
291 switch (mode & (MD(14) | MD(13))) { 296 switch (mode & (MD(14) | MD(13))) {
292 case 0: 297 case 0:
293 R8A7790_CLOCK_ROOT(15, &extal_clk, 172, 208, 106, 88); 298 R8A7790_CLOCK_ROOT(15, &extal_clk, 172, 208, 106, 88);
diff --git a/arch/arm/mach-shmobile/include/mach/emev2.h b/arch/arm/mach-shmobile/include/mach/emev2.h
index b0ab4b72770a..c2eb7568d9be 100644
--- a/arch/arm/mach-shmobile/include/mach/emev2.h
+++ b/arch/arm/mach-shmobile/include/mach/emev2.h
@@ -5,7 +5,6 @@ extern void emev2_map_io(void);
5extern void emev2_init_delay(void); 5extern void emev2_init_delay(void);
6extern void emev2_add_standard_devices(void); 6extern void emev2_add_standard_devices(void);
7extern void emev2_clock_init(void); 7extern void emev2_clock_init(void);
8extern void emev2_set_boot_vector(unsigned long value);
9 8
10#define EMEV2_GPIO_BASE 200 9#define EMEV2_GPIO_BASE 200
11#define EMEV2_GPIO_IRQ(n) (EMEV2_GPIO_BASE + (n)) 10#define EMEV2_GPIO_IRQ(n) (EMEV2_GPIO_BASE + (n))
diff --git a/arch/arm/mach-shmobile/include/mach/r8a73a4.h b/arch/arm/mach-shmobile/include/mach/r8a73a4.h
index f043103e32c9..144a85e29245 100644
--- a/arch/arm/mach-shmobile/include/mach/r8a73a4.h
+++ b/arch/arm/mach-shmobile/include/mach/r8a73a4.h
@@ -4,5 +4,6 @@
4void r8a73a4_add_standard_devices(void); 4void r8a73a4_add_standard_devices(void);
5void r8a73a4_clock_init(void); 5void r8a73a4_clock_init(void);
6void r8a73a4_pinmux_init(void); 6void r8a73a4_pinmux_init(void);
7void r8a73a4_init_delay(void);
7 8
8#endif /* __ASM_R8A73A4_H__ */ 9#endif /* __ASM_R8A73A4_H__ */
diff --git a/arch/arm/mach-shmobile/include/mach/r8a7740.h b/arch/arm/mach-shmobile/include/mach/r8a7740.h
index b34d19b5ca5c..56f375005fcd 100644
--- a/arch/arm/mach-shmobile/include/mach/r8a7740.h
+++ b/arch/arm/mach-shmobile/include/mach/r8a7740.h
@@ -42,6 +42,8 @@ enum {
42 SHDMA_SLAVE_FSIB_TX, 42 SHDMA_SLAVE_FSIB_TX,
43 SHDMA_SLAVE_USBHS_TX, 43 SHDMA_SLAVE_USBHS_TX,
44 SHDMA_SLAVE_USBHS_RX, 44 SHDMA_SLAVE_USBHS_RX,
45 SHDMA_SLAVE_MMCIF_TX,
46 SHDMA_SLAVE_MMCIF_RX,
45}; 47};
46 48
47extern void r8a7740_meram_workaround(void); 49extern void r8a7740_meram_workaround(void);
diff --git a/arch/arm/mach-shmobile/include/mach/r8a7790.h b/arch/arm/mach-shmobile/include/mach/r8a7790.h
index 2e919e61fa0d..7aaef409a059 100644
--- a/arch/arm/mach-shmobile/include/mach/r8a7790.h
+++ b/arch/arm/mach-shmobile/include/mach/r8a7790.h
@@ -4,6 +4,10 @@
4void r8a7790_add_standard_devices(void); 4void r8a7790_add_standard_devices(void);
5void r8a7790_clock_init(void); 5void r8a7790_clock_init(void);
6void r8a7790_pinmux_init(void); 6void r8a7790_pinmux_init(void);
7void r8a7790_init_delay(void);
7void r8a7790_timer_init(void); 8void r8a7790_timer_init(void);
8 9
10#define MD(nr) BIT(nr)
11u32 r8a7790_read_mode_pins(void);
12
9#endif /* __ASM_R8A7790_H__ */ 13#endif /* __ASM_R8A7790_H__ */
diff --git a/arch/arm/mach-shmobile/setup-r8a73a4.c b/arch/arm/mach-shmobile/setup-r8a73a4.c
index a8c4e41bf27a..d533bd23865c 100644
--- a/arch/arm/mach-shmobile/setup-r8a73a4.c
+++ b/arch/arm/mach-shmobile/setup-r8a73a4.c
@@ -22,6 +22,7 @@
22#include <linux/of_platform.h> 22#include <linux/of_platform.h>
23#include <linux/platform_data/irq-renesas-irqc.h> 23#include <linux/platform_data/irq-renesas-irqc.h>
24#include <linux/serial_sci.h> 24#include <linux/serial_sci.h>
25#include <linux/sh_timer.h>
25#include <mach/common.h> 26#include <mach/common.h>
26#include <mach/irqs.h> 27#include <mach/irqs.h>
27#include <mach/r8a73a4.h> 28#include <mach/r8a73a4.h>
@@ -168,6 +169,25 @@ static const struct resource thermal0_resources[] = {
168 thermal0_resources, \ 169 thermal0_resources, \
169 ARRAY_SIZE(thermal0_resources)) 170 ARRAY_SIZE(thermal0_resources))
170 171
172static struct sh_timer_config cmt10_platform_data = {
173 .name = "CMT10",
174 .timer_bit = 0,
175 .clockevent_rating = 80,
176};
177
178static struct resource cmt10_resources[] = {
179 DEFINE_RES_MEM(0xe6130010, 0x0c),
180 DEFINE_RES_MEM(0xe6130000, 0x04),
181 DEFINE_RES_IRQ(gic_spi(120)), /* CMT1_0 */
182};
183
184#define r8a7790_register_cmt(idx) \
185 platform_device_register_resndata(&platform_bus, "sh_cmt", \
186 idx, cmt##idx##_resources, \
187 ARRAY_SIZE(cmt##idx##_resources), \
188 &cmt##idx##_platform_data, \
189 sizeof(struct sh_timer_config))
190
171void __init r8a73a4_add_standard_devices(void) 191void __init r8a73a4_add_standard_devices(void)
172{ 192{
173 r8a73a4_register_scif(SCIFA0); 193 r8a73a4_register_scif(SCIFA0);
@@ -179,11 +199,20 @@ void __init r8a73a4_add_standard_devices(void)
179 r8a73a4_register_irqc(0); 199 r8a73a4_register_irqc(0);
180 r8a73a4_register_irqc(1); 200 r8a73a4_register_irqc(1);
181 r8a73a4_register_thermal(); 201 r8a73a4_register_thermal();
202 r8a7790_register_cmt(10);
203}
204
205void __init r8a73a4_init_delay(void)
206{
207#ifndef CONFIG_ARM_ARCH_TIMER
208 shmobile_setup_delay(1500, 2, 4); /* Cortex-A15 @ 1500MHz */
209#endif
182} 210}
183 211
184#ifdef CONFIG_USE_OF 212#ifdef CONFIG_USE_OF
185void __init r8a73a4_add_standard_devices_dt(void) 213void __init r8a73a4_add_standard_devices_dt(void)
186{ 214{
215 platform_device_register_simple("cpufreq-cpu0", -1, NULL, 0);
187 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); 216 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
188} 217}
189 218
@@ -193,6 +222,7 @@ static const char *r8a73a4_boards_compat_dt[] __initdata = {
193}; 222};
194 223
195DT_MACHINE_START(R8A73A4_DT, "Generic R8A73A4 (Flattened Device Tree)") 224DT_MACHINE_START(R8A73A4_DT, "Generic R8A73A4 (Flattened Device Tree)")
225 .init_early = r8a73a4_init_delay,
196 .init_machine = r8a73a4_add_standard_devices_dt, 226 .init_machine = r8a73a4_add_standard_devices_dt,
197 .init_time = shmobile_timer_init, 227 .init_time = shmobile_timer_init,
198 .dt_compat = r8a73a4_boards_compat_dt, 228 .dt_compat = r8a73a4_boards_compat_dt,
diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c
index ac29c2ee011f..84c5bb6d9725 100644
--- a/arch/arm/mach-shmobile/setup-r8a7740.c
+++ b/arch/arm/mach-shmobile/setup-r8a7740.c
@@ -588,6 +588,16 @@ static const struct sh_dmae_slave_config r8a7740_dmae_slaves[] = {
588 .addr = 0xfe1f0064, 588 .addr = 0xfe1f0064,
589 .chcr = CHCR_TX(XMIT_SZ_32BIT), 589 .chcr = CHCR_TX(XMIT_SZ_32BIT),
590 .mid_rid = 0xb5, 590 .mid_rid = 0xb5,
591 }, {
592 .slave_id = SHDMA_SLAVE_MMCIF_TX,
593 .addr = 0xe6bd0034,
594 .chcr = CHCR_TX(XMIT_SZ_32BIT),
595 .mid_rid = 0xd1,
596 }, {
597 .slave_id = SHDMA_SLAVE_MMCIF_RX,
598 .addr = 0xe6bd0034,
599 .chcr = CHCR_RX(XMIT_SZ_32BIT),
600 .mid_rid = 0xd2,
591 }, 601 },
592}; 602};
593 603
diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c
index b7e78b9a7fdf..4c96dad21195 100644
--- a/arch/arm/mach-shmobile/setup-r8a7790.c
+++ b/arch/arm/mach-shmobile/setup-r8a7790.c
@@ -21,9 +21,10 @@
21#include <linux/irq.h> 21#include <linux/irq.h>
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/of_platform.h> 23#include <linux/of_platform.h>
24#include <linux/serial_sci.h>
25#include <linux/platform_data/gpio-rcar.h> 24#include <linux/platform_data/gpio-rcar.h>
26#include <linux/platform_data/irq-renesas-irqc.h> 25#include <linux/platform_data/irq-renesas-irqc.h>
26#include <linux/serial_sci.h>
27#include <linux/sh_timer.h>
27#include <mach/common.h> 28#include <mach/common.h>
28#include <mach/irqs.h> 29#include <mach/irqs.h>
29#include <mach/r8a7790.h> 30#include <mach/r8a7790.h>
@@ -148,6 +149,36 @@ static struct resource irqc0_resources[] __initdata = {
148 &irqc##idx##_data, \ 149 &irqc##idx##_data, \
149 sizeof(struct renesas_irqc_config)) 150 sizeof(struct renesas_irqc_config))
150 151
152static struct resource thermal_resources[] __initdata = {
153 DEFINE_RES_MEM(0xe61f0000, 0x14),
154 DEFINE_RES_MEM(0xe61f0100, 0x38),
155 DEFINE_RES_IRQ(gic_spi(69)),
156};
157
158#define r8a7790_register_thermal() \
159 platform_device_register_simple("rcar_thermal", -1, \
160 thermal_resources, \
161 ARRAY_SIZE(thermal_resources))
162
163static struct sh_timer_config cmt00_platform_data = {
164 .name = "CMT00",
165 .timer_bit = 0,
166 .clockevent_rating = 80,
167};
168
169static struct resource cmt00_resources[] = {
170 DEFINE_RES_MEM(0xffca0510, 0x0c),
171 DEFINE_RES_MEM(0xffca0500, 0x04),
172 DEFINE_RES_IRQ(gic_spi(142)), /* CMT0_0 */
173};
174
175#define r8a7790_register_cmt(idx) \
176 platform_device_register_resndata(&platform_bus, "sh_cmt", \
177 idx, cmt##idx##_resources, \
178 ARRAY_SIZE(cmt##idx##_resources), \
179 &cmt##idx##_platform_data, \
180 sizeof(struct sh_timer_config))
181
151void __init r8a7790_add_standard_devices(void) 182void __init r8a7790_add_standard_devices(void)
152{ 183{
153 r8a7790_register_scif(SCIFA0); 184 r8a7790_register_scif(SCIFA0);
@@ -161,20 +192,82 @@ void __init r8a7790_add_standard_devices(void)
161 r8a7790_register_scif(HSCIF0); 192 r8a7790_register_scif(HSCIF0);
162 r8a7790_register_scif(HSCIF1); 193 r8a7790_register_scif(HSCIF1);
163 r8a7790_register_irqc(0); 194 r8a7790_register_irqc(0);
195 r8a7790_register_thermal();
196 r8a7790_register_cmt(00);
164} 197}
165 198
199#define MODEMR 0xe6160060
200
201u32 __init r8a7790_read_mode_pins(void)
202{
203 void __iomem *modemr = ioremap_nocache(MODEMR, 4);
204 u32 mode;
205
206 BUG_ON(!modemr);
207 mode = ioread32(modemr);
208 iounmap(modemr);
209
210 return mode;
211}
212
213#define CNTCR 0
214#define CNTFID0 0x20
215
166void __init r8a7790_timer_init(void) 216void __init r8a7790_timer_init(void)
167{ 217{
168 void __iomem *cntcr; 218#ifdef CONFIG_ARM_ARCH_TIMER
219 u32 mode = r8a7790_read_mode_pins();
220 void __iomem *base;
221 int extal_mhz = 0;
222 u32 freq;
223
224 /* At Linux boot time the r8a7790 arch timer comes up
225 * with the counter disabled. Moreover, it may also report
226 * a potentially incorrect fixed 13 MHz frequency. To be
227 * correct these registers need to be updated to use the
228 * frequency EXTAL / 2 which can be determined by the MD pins.
229 */
230
231 switch (mode & (MD(14) | MD(13))) {
232 case 0:
233 extal_mhz = 15;
234 break;
235 case MD(13):
236 extal_mhz = 20;
237 break;
238 case MD(14):
239 extal_mhz = 26;
240 break;
241 case MD(13) | MD(14):
242 extal_mhz = 30;
243 break;
244 }
169 245
170 /* make sure arch timer is started by setting bit 0 of CNTCT */ 246 /* The arch timer frequency equals EXTAL / 2 */
171 cntcr = ioremap(0xe6080000, PAGE_SIZE); 247 freq = extal_mhz * (1000000 / 2);
172 iowrite32(1, cntcr); 248
173 iounmap(cntcr); 249 /* Remap "armgcnt address map" space */
250 base = ioremap(0xe6080000, PAGE_SIZE);
251
252 /* Update registers with correct frequency */
253 iowrite32(freq, base + CNTFID0);
254 asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r" (freq));
255
256 /* make sure arch timer is started by setting bit 0 of CNTCR */
257 iowrite32(1, base + CNTCR);
258 iounmap(base);
259#endif /* CONFIG_ARM_ARCH_TIMER */
174 260
175 shmobile_timer_init(); 261 shmobile_timer_init();
176} 262}
177 263
264void __init r8a7790_init_delay(void)
265{
266#ifndef CONFIG_ARM_ARCH_TIMER
267 shmobile_setup_delay(1300, 2, 4); /* Cortex-A15 @ 1300MHz */
268#endif
269}
270
178#ifdef CONFIG_USE_OF 271#ifdef CONFIG_USE_OF
179 272
180static const char *r8a7790_boards_compat_dt[] __initdata = { 273static const char *r8a7790_boards_compat_dt[] __initdata = {
@@ -183,6 +276,7 @@ static const char *r8a7790_boards_compat_dt[] __initdata = {
183}; 276};
184 277
185DT_MACHINE_START(R8A7790_DT, "Generic R8A7790 (Flattened Device Tree)") 278DT_MACHINE_START(R8A7790_DT, "Generic R8A7790 (Flattened Device Tree)")
279 .init_early = r8a7790_init_delay,
186 .init_time = r8a7790_timer_init, 280 .init_time = r8a7790_timer_init,
187 .dt_compat = r8a7790_boards_compat_dt, 281 .dt_compat = r8a7790_boards_compat_dt,
188MACHINE_END 282MACHINE_END
diff --git a/arch/arm/mach-shmobile/smp-emev2.c b/arch/arm/mach-shmobile/smp-emev2.c
index 1fcd607d64ad..78e84c582453 100644
--- a/arch/arm/mach-shmobile/smp-emev2.c
+++ b/arch/arm/mach-shmobile/smp-emev2.c
@@ -29,6 +29,8 @@
29#include <asm/smp_scu.h> 29#include <asm/smp_scu.h>
30 30
31#define EMEV2_SCU_BASE 0x1e000000 31#define EMEV2_SCU_BASE 0x1e000000
32#define EMEV2_SMU_BASE 0xe0110000
33#define SMU_GENERAL_REG0 0x7c0
32 34
33static int emev2_boot_secondary(unsigned int cpu, struct task_struct *idle) 35static int emev2_boot_secondary(unsigned int cpu, struct task_struct *idle)
34{ 36{
@@ -38,13 +40,18 @@ static int emev2_boot_secondary(unsigned int cpu, struct task_struct *idle)
38 40
39static void __init emev2_smp_prepare_cpus(unsigned int max_cpus) 41static void __init emev2_smp_prepare_cpus(unsigned int max_cpus)
40{ 42{
43 void __iomem *smu;
44
41 /* setup EMEV2 specific SCU base, enable */ 45 /* setup EMEV2 specific SCU base, enable */
42 shmobile_scu_base = ioremap(EMEV2_SCU_BASE, PAGE_SIZE); 46 shmobile_scu_base = ioremap(EMEV2_SCU_BASE, PAGE_SIZE);
43 scu_enable(shmobile_scu_base); 47 scu_enable(shmobile_scu_base);
44 48
45 /* Tell ROM loader about our vector (in headsmp-scu.S, headsmp.S) */ 49 /* Tell ROM loader about our vector (in headsmp-scu.S, headsmp.S) */
46 emev2_clock_init(); /* need ioremapped SMU */ 50 smu = ioremap(EMEV2_SMU_BASE, PAGE_SIZE);
47 emev2_set_boot_vector(__pa(shmobile_boot_vector)); 51 if (smu) {
52 iowrite32(__pa(shmobile_boot_vector), smu + SMU_GENERAL_REG0);
53 iounmap(smu);
54 }
48 shmobile_boot_fn = virt_to_phys(shmobile_boot_scu); 55 shmobile_boot_fn = virt_to_phys(shmobile_boot_scu);
49 shmobile_boot_arg = (unsigned long)shmobile_scu_base; 56 shmobile_boot_arg = (unsigned long)shmobile_scu_base;
50 57