From 5c4dfcd663b6e96cc20f02dc2c7c315749ea1bc1 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 8 Aug 2013 07:13:30 +0900 Subject: ARM: shmobile: Introduce shmobile_smp_cpu_disable() Introduce the shared CPU Hotplug function shmobile_smp_cpu_disable() for mach-shmobile. It is useful for the case when all CPUs may be hotplugged, including CPU 0. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/include/mach/common.h | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/arm/mach-shmobile/include') diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h index 7b938681e756..1ed155eb3e92 100644 --- a/arch/arm/mach-shmobile/include/mach/common.h +++ b/arch/arm/mach-shmobile/include/mach/common.h @@ -13,6 +13,7 @@ extern void shmobile_smp_boot(void); extern void shmobile_smp_sleep(void); extern void shmobile_smp_hook(unsigned int cpu, unsigned long fn, unsigned long arg); +extern int shmobile_smp_cpu_disable(unsigned int cpu); extern void shmobile_boot_scu(void); extern void shmobile_smp_scu_prepare_cpus(unsigned int max_cpus); extern int shmobile_smp_scu_boot_secondary(unsigned int cpu, -- cgit v1.2.3 From c4e1e64d2b6a921a57629ede635f81f5d2882543 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 8 Aug 2013 07:13:49 +0900 Subject: ARM: shmobile: Remove unused shmobile_smp_init_cpus() Remove shmobile_smp_init_cpus() since all SMP platforms in mach-shmobile now rely on DT for CPU core description instead of for instance determining number of cores from the SCU. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/include/mach/common.h | 1 - arch/arm/mach-shmobile/platsmp.c | 15 --------------- 2 files changed, 16 deletions(-) (limited to 'arch/arm/mach-shmobile/include') diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h index 1ed155eb3e92..26eaff1429bf 100644 --- a/arch/arm/mach-shmobile/include/mach/common.h +++ b/arch/arm/mach-shmobile/include/mach/common.h @@ -40,7 +40,6 @@ static inline int shmobile_cpuidle_init(void) { return 0; } #endif extern void __iomem *shmobile_scu_base; -extern void shmobile_smp_init_cpus(unsigned int ncores); static inline void __init shmobile_init_late(void) { diff --git a/arch/arm/mach-shmobile/platsmp.c b/arch/arm/mach-shmobile/platsmp.c index 3741562156ed..9ebc246b8d7d 100644 --- a/arch/arm/mach-shmobile/platsmp.c +++ b/arch/arm/mach-shmobile/platsmp.c @@ -11,25 +11,10 @@ * published by the Free Software Foundation. */ #include -#include #include #include #include -void __init shmobile_smp_init_cpus(unsigned int ncores) -{ - unsigned int i; - - if (ncores > nr_cpu_ids) { - pr_warn("SMP: %u cores greater than maximum (%u), clipping\n", - ncores, nr_cpu_ids); - ncores = nr_cpu_ids; - } - - for (i = 0; i < ncores; i++) - set_cpu_possible(i, true); -} - extern unsigned long shmobile_smp_fn[]; extern unsigned long shmobile_smp_arg[]; extern unsigned long shmobile_smp_mpidr[]; -- cgit v1.2.3 From 87a08ca0f7f99b3136c763377c547a89cf6d0996 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 8 Aug 2013 07:13:58 +0900 Subject: ARM: shmobile: Expose shmobile_invalidate_start() Expose shmobile_invalidate_start() in common.h for mach-shmobile. This function will be used for boot of secondary processors on future non-SCU SMP platforms. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/include/mach/common.h | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/arm/mach-shmobile/include') diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h index 26eaff1429bf..a9df8f3bfda7 100644 --- a/arch/arm/mach-shmobile/include/mach/common.h +++ b/arch/arm/mach-shmobile/include/mach/common.h @@ -14,6 +14,7 @@ extern void shmobile_smp_sleep(void); extern void shmobile_smp_hook(unsigned int cpu, unsigned long fn, unsigned long arg); extern int shmobile_smp_cpu_disable(unsigned int cpu); +extern void shmobile_invalidate_start(void); extern void shmobile_boot_scu(void); extern void shmobile_smp_scu_prepare_cpus(unsigned int max_cpus); extern int shmobile_smp_scu_boot_secondary(unsigned int cpu, -- cgit v1.2.3 From a84a5ab73f77a5dd4f09f0af33f09d8d751d0cc7 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 8 Aug 2013 07:14:07 +0900 Subject: ARM: shmobile: Introduce shmobile_boot_size Introduce shmobile_boot_size that can be used by future SMP code to determine the size of the boot code that needs to be copied to internal SRAM. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/headsmp.S | 3 +++ arch/arm/mach-shmobile/include/mach/common.h | 1 + 2 files changed, 4 insertions(+) (limited to 'arch/arm/mach-shmobile/include') diff --git a/arch/arm/mach-shmobile/headsmp.S b/arch/arm/mach-shmobile/headsmp.S index f93751caf5cb..e5be5c88644b 100644 --- a/arch/arm/mach-shmobile/headsmp.S +++ b/arch/arm/mach-shmobile/headsmp.S @@ -40,6 +40,9 @@ shmobile_boot_fn: .globl shmobile_boot_arg shmobile_boot_arg: 2: .space 4 + .globl shmobile_boot_size +shmobile_boot_size: + .long . - shmobile_boot_vector /* * Per-CPU SMP boot function/argument selection code based on MPIDR diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h index a9df8f3bfda7..cfe397716fd1 100644 --- a/arch/arm/mach-shmobile/include/mach/common.h +++ b/arch/arm/mach-shmobile/include/mach/common.h @@ -9,6 +9,7 @@ extern void shmobile_setup_console(void); extern void shmobile_boot_vector(void); extern unsigned long shmobile_boot_fn; extern unsigned long shmobile_boot_arg; +extern unsigned long shmobile_boot_size; extern void shmobile_smp_boot(void); extern void shmobile_smp_sleep(void); extern void shmobile_smp_hook(unsigned int cpu, unsigned long fn, -- cgit v1.2.3 From 0d0771ab2bd5f57a62db91f26bba1e9f522d16cb Mon Sep 17 00:00:00 2001 From: Hisashi Nakamura Date: Wed, 4 Sep 2013 12:45:57 +0900 Subject: ARM: shmobile: Initial r8a7791 SoC support Add initial support for the r8a7791 SoC including: - Single Cortex-A15 CPU Core - GIC No static virtual mappings are used, all the components make use of ioremap(). DT_MACHINE_START is still wrapped in CONFIG_USE_OF to match other mach-shmobile code. Signed-off-by: Hisashi Nakamura Signed-off-by: Ryo Kataoka [damm@opensource.se: Forward ported to upstream, dropped not-yet-ready code] Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7791.dtsi | 41 ++++++ arch/arm/mach-shmobile/Kconfig | 6 + arch/arm/mach-shmobile/Makefile | 2 + arch/arm/mach-shmobile/clock-r8a7791.c | 198 ++++++++++++++++++++++++++ arch/arm/mach-shmobile/include/mach/r8a7791.h | 6 + arch/arm/mach-shmobile/setup-r8a7791.c | 38 +++++ 6 files changed, 291 insertions(+) create mode 100644 arch/arm/boot/dts/r8a7791.dtsi create mode 100644 arch/arm/mach-shmobile/clock-r8a7791.c create mode 100644 arch/arm/mach-shmobile/include/mach/r8a7791.h create mode 100644 arch/arm/mach-shmobile/setup-r8a7791.c (limited to 'arch/arm/mach-shmobile/include') diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi new file mode 100644 index 000000000000..bbed43bd9be9 --- /dev/null +++ b/arch/arm/boot/dts/r8a7791.dtsi @@ -0,0 +1,41 @@ +/* + * Device Tree Source for the r8a7791 SoC + * + * Copyright (C) 2013 Renesas Electronics Corporation + * Copyright (C) 2013 Renesas Solutions Corp. + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +/ { + compatible = "renesas,r8a7791"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0>; + clock-frequency = <1300000000>; + }; + }; + + gic: interrupt-controller@f1001000 { + compatible = "arm,cortex-a15-gic"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + reg = <0 0xf1001000 0 0x1000>, + <0 0xf1002000 0 0x1000>, + <0 0xf1004000 0 0x2000>, + <0 0xf1006000 0 0x2000>; + interrupts = <1 9 0xf04>; + }; +}; diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index 1f94c310c477..b45240512ce0 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig @@ -101,6 +101,12 @@ config ARCH_R8A7790 select SH_CLK_CPG select RENESAS_IRQC +config ARCH_R8A7791 + bool "R-Car M2 (R8A77910)" + select ARM_GIC + select CPU_V7 + select SH_CLK_CPG + config ARCH_EMEV2 bool "Emma Mobile EV2" select ARCH_WANT_OPTIONAL_GPIOLIB diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index 2705bfa8c113..228193cc9a38 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_ARCH_R8A7740) += setup-r8a7740.o obj-$(CONFIG_ARCH_R8A7778) += setup-r8a7778.o obj-$(CONFIG_ARCH_R8A7779) += setup-r8a7779.o obj-$(CONFIG_ARCH_R8A7790) += setup-r8a7790.o +obj-$(CONFIG_ARCH_R8A7791) += setup-r8a7791.o obj-$(CONFIG_ARCH_EMEV2) += setup-emev2.o # Clock objects @@ -27,6 +28,7 @@ obj-$(CONFIG_ARCH_R8A7740) += clock-r8a7740.o obj-$(CONFIG_ARCH_R8A7778) += clock-r8a7778.o obj-$(CONFIG_ARCH_R8A7779) += clock-r8a7779.o obj-$(CONFIG_ARCH_R8A7790) += clock-r8a7790.o +obj-$(CONFIG_ARCH_R8A7791) += clock-r8a7791.o obj-$(CONFIG_ARCH_EMEV2) += clock-emev2.o endif diff --git a/arch/arm/mach-shmobile/clock-r8a7791.c b/arch/arm/mach-shmobile/clock-r8a7791.c new file mode 100644 index 000000000000..9929feb1b810 --- /dev/null +++ b/arch/arm/mach-shmobile/clock-r8a7791.c @@ -0,0 +1,198 @@ +/* + * r8a7791 clock framework support + * + * Copyright (C) 2013 Renesas Electronics Corporation + * Copyright (C) 2013 Renesas Solutions Corp. + * Copyright (C) 2013 Magnus Damm + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include +#include +#include +#include +#include +#include +#include + +/* + * MD EXTAL PLL0 PLL1 PLL3 + * 14 13 19 (MHz) *1 *1 + *--------------------------------------------------- + * 0 0 0 15 x 1 x172/2 x208/2 x106 + * 0 0 1 15 x 1 x172/2 x208/2 x88 + * 0 1 0 20 x 1 x130/2 x156/2 x80 + * 0 1 1 20 x 1 x130/2 x156/2 x66 + * 1 0 0 26 / 2 x200/2 x240/2 x122 + * 1 0 1 26 / 2 x200/2 x240/2 x102 + * 1 1 0 30 / 2 x172/2 x208/2 x106 + * 1 1 1 30 / 2 x172/2 x208/2 x88 + * + * *1 : Table 7.6 indicates VCO ouput (PLLx = VCO/2) + * see "p1 / 2" on R8A7791_CLOCK_ROOT() below + */ + +#define MD(nr) (1 << nr) + +#define CPG_BASE 0xe6150000 +#define CPG_LEN 0x1000 + +#define SMSTPCR1 0xE6150134 +#define SMSTPCR2 0xe6150138 +#define SMSTPCR3 0xE615013C +#define SMSTPCR5 0xE6150144 +#define SMSTPCR7 0xe615014c +#define SMSTPCR8 0xE6150990 +#define SMSTPCR9 0xE6150994 +#define SMSTPCR10 0xE6150998 + +#define MODEMR 0xE6160060 +#define SDCKCR 0xE6150074 +#define SD2CKCR 0xE6150078 +#define SD3CKCR 0xE615007C +#define MMC0CKCR 0xE6150240 +#define MMC1CKCR 0xE6150244 +#define SSPCKCR 0xE6150248 +#define SSPRSCKCR 0xE615024C + +static struct clk_mapping cpg_mapping = { + .phys = CPG_BASE, + .len = CPG_LEN, +}; + +static struct clk extal_clk = { + /* .rate will be updated on r8a7791_clock_init() */ + .mapping = &cpg_mapping, +}; + +static struct sh_clk_ops followparent_clk_ops = { + .recalc = followparent_recalc, +}; + +static struct clk main_clk = { + /* .parent will be set r8a73a4_clock_init */ + .ops = &followparent_clk_ops, +}; + +/* + * clock ratio of these clock will be updated + * on r8a7791_clock_init() + */ +SH_FIXED_RATIO_CLK_SET(pll1_clk, main_clk, 1, 1); +SH_FIXED_RATIO_CLK_SET(pll3_clk, main_clk, 1, 1); + +/* fixed ratio clock */ +SH_FIXED_RATIO_CLK_SET(extal_div2_clk, extal_clk, 1, 2); +SH_FIXED_RATIO_CLK_SET(cp_clk, extal_clk, 1, 2); + +SH_FIXED_RATIO_CLK_SET(pll1_div2_clk, pll1_clk, 1, 2); +SH_FIXED_RATIO_CLK_SET(hp_clk, pll1_clk, 1, 12); +SH_FIXED_RATIO_CLK_SET(p_clk, pll1_clk, 1, 24); + +SH_FIXED_RATIO_CLK_SET(mp_clk, pll1_div2_clk, 1, 15); + +static struct clk *main_clks[] = { + &extal_clk, + &extal_div2_clk, + &main_clk, + &pll1_clk, + &pll1_div2_clk, + &pll3_clk, + &hp_clk, + &p_clk, + &mp_clk, + &cp_clk, +}; + +/* MSTP */ +enum { + MSTP721, MSTP720, +/* MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202,*/ + MSTP_NR +}; + +static struct clk mstp_clks[MSTP_NR] = { + [MSTP721] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 21, 0), /* SCIF0 */ + [MSTP720] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 20, 0), /* SCIF1 */ +}; + +static struct clk_lookup lookups[] = { + + /* main clocks */ + CLKDEV_CON_ID("extal", &extal_clk), + CLKDEV_CON_ID("extal_div2", &extal_div2_clk), + CLKDEV_CON_ID("main", &main_clk), + CLKDEV_CON_ID("pll1", &pll1_clk), + CLKDEV_CON_ID("pll1_div2", &pll1_div2_clk), + CLKDEV_CON_ID("pll3", &pll3_clk), + CLKDEV_CON_ID("hp", &hp_clk), + CLKDEV_CON_ID("p", &p_clk), + CLKDEV_CON_ID("mp", &mp_clk), + CLKDEV_CON_ID("cp", &cp_clk), + CLKDEV_CON_ID("peripheral_clk", &hp_clk), +}; + +#define R8A7791_CLOCK_ROOT(e, m, p0, p1, p30, p31) \ + extal_clk.rate = e * 1000 * 1000; \ + main_clk.parent = m; \ + SH_CLK_SET_RATIO(&pll1_clk_ratio, p1 / 2, 1); \ + if (mode & MD(19)) \ + SH_CLK_SET_RATIO(&pll3_clk_ratio, p31, 1); \ + else \ + SH_CLK_SET_RATIO(&pll3_clk_ratio, p30, 1) + + +void __init r8a7791_clock_init(void) +{ + void __iomem *modemr = ioremap_nocache(MODEMR, PAGE_SIZE); + u32 mode; + int k, ret = 0; + + BUG_ON(!modemr); + mode = ioread32(modemr); + iounmap(modemr); + + switch (mode & (MD(14) | MD(13))) { + case 0: + R8A7791_CLOCK_ROOT(15, &extal_clk, 172, 208, 106, 88); + break; + case MD(13): + R8A7791_CLOCK_ROOT(20, &extal_clk, 130, 156, 80, 66); + break; + case MD(14): + R8A7791_CLOCK_ROOT(26, &extal_div2_clk, 200, 240, 122, 102); + break; + case MD(13) | MD(14): + R8A7791_CLOCK_ROOT(30, &extal_div2_clk, 172, 208, 106, 88); + break; + } + + for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) + ret = clk_register(main_clks[k]); + + if (!ret) + ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); + + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); + + if (!ret) + shmobile_clk_init(); + else + goto epanic; + + return; + +epanic: + panic("failed to setup r8a7791 clocks\n"); +} diff --git a/arch/arm/mach-shmobile/include/mach/r8a7791.h b/arch/arm/mach-shmobile/include/mach/r8a7791.h new file mode 100644 index 000000000000..43b7206998da --- /dev/null +++ b/arch/arm/mach-shmobile/include/mach/r8a7791.h @@ -0,0 +1,6 @@ +#ifndef __ASM_R8A7791_H__ +#define __ASM_R8A7791_H__ + +void r8a7791_clock_init(void); + +#endif /* __ASM_R8A7791_H__ */ diff --git a/arch/arm/mach-shmobile/setup-r8a7791.c b/arch/arm/mach-shmobile/setup-r8a7791.c new file mode 100644 index 000000000000..88dcce1a6391 --- /dev/null +++ b/arch/arm/mach-shmobile/setup-r8a7791.c @@ -0,0 +1,38 @@ +/* + * r8a7791 processor support + * + * Copyright (C) 2013 Renesas Electronics Corporation + * Copyright (C) 2013 Renesas Solutions Corp. + * Copyright (C) 2013 Magnus Damm + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_USE_OF +static const char *r8a7791_boards_compat_dt[] __initdata = { + "renesas,r8a7791", + NULL, +}; + +DT_MACHINE_START(R8A7791_DT, "Generic R8A7791 (Flattened Device Tree)") + .dt_compat = r8a7791_boards_compat_dt, +MACHINE_END +#endif /* CONFIG_USE_OF */ -- cgit v1.2.3 From e6491d08ed1d5d1e415d5371f2ff2fed67df83b0 Mon Sep 17 00:00:00 2001 From: Yoshikazu Fujikawa Date: Wed, 4 Sep 2013 12:46:08 +0900 Subject: ARM: shmobile: r8a7791 SCIF support Add SCIF serial port support to the r8a7791 SoC by adding platform devices for SCIFA0 -> SCIFA5 as well as SCIFB0 -> SCIFB2 and SCIF0 -> SCIF5 together with clock bindings. DT device description is excluded at this point since such bindings are still under development. Signed-off-by: Yoshikazu Fujikawa Signed-off-by: Ryo Kataoka [damm@opensource.se: Forward ported to upstream, dropped holes in enum] Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/clock-r8a7791.c | 36 +++++++++++- arch/arm/mach-shmobile/include/mach/r8a7791.h | 1 + arch/arm/mach-shmobile/setup-r8a7791.c | 82 +++++++++++++++++++++++++++ 3 files changed, 118 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-shmobile/include') diff --git a/arch/arm/mach-shmobile/clock-r8a7791.c b/arch/arm/mach-shmobile/clock-r8a7791.c index 9929feb1b810..df3122ea4c69 100644 --- a/arch/arm/mach-shmobile/clock-r8a7791.c +++ b/arch/arm/mach-shmobile/clock-r8a7791.c @@ -48,6 +48,7 @@ #define CPG_BASE 0xe6150000 #define CPG_LEN 0x1000 +#define SMSTPCR0 0xE6150130 #define SMSTPCR1 0xE6150134 #define SMSTPCR2 0xe6150138 #define SMSTPCR3 0xE615013C @@ -56,6 +57,7 @@ #define SMSTPCR8 0xE6150990 #define SMSTPCR9 0xE6150994 #define SMSTPCR10 0xE6150998 +#define SMSTPCR11 0xE615099C #define MODEMR 0xE6160060 #define SDCKCR 0xE6150074 @@ -118,13 +120,28 @@ static struct clk *main_clks[] = { /* MSTP */ enum { MSTP721, MSTP720, -/* MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202,*/ + MSTP719, MSTP718, MSTP715, MSTP714, + MSTP216, MSTP207, MSTP206, + MSTP204, MSTP203, MSTP202, MSTP1105, MSTP1106, MSTP1107, MSTP_NR }; static struct clk mstp_clks[MSTP_NR] = { [MSTP721] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 21, 0), /* SCIF0 */ [MSTP720] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 20, 0), /* SCIF1 */ + [MSTP719] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 19, 0), /* SCIF2 */ + [MSTP718] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 18, 0), /* SCIF3 */ + [MSTP715] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 15, 0), /* SCIF4 */ + [MSTP714] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 14, 0), /* SCIF5 */ + [MSTP216] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 16, 0), /* SCIFB2 */ + [MSTP207] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 7, 0), /* SCIFB1 */ + [MSTP206] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 6, 0), /* SCIFB0 */ + [MSTP204] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 4, 0), /* SCIFA0 */ + [MSTP203] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 3, 0), /* SCIFA1 */ + [MSTP202] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 2, 0), /* SCIFA2 */ + [MSTP1105] = SH_CLK_MSTP32(&mp_clk, SMSTPCR11, 5, 0), /* SCIFA3 */ + [MSTP1106] = SH_CLK_MSTP32(&mp_clk, SMSTPCR11, 6, 0), /* SCIFA4 */ + [MSTP1107] = SH_CLK_MSTP32(&mp_clk, SMSTPCR11, 7, 0), /* SCIFA5 */ }; static struct clk_lookup lookups[] = { @@ -141,6 +158,23 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("mp", &mp_clk), CLKDEV_CON_ID("cp", &cp_clk), CLKDEV_CON_ID("peripheral_clk", &hp_clk), + + /* MSTP */ + CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */ + CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */ + CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP206]), /* SCIFB0 */ + CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP207]), /* SCIFB1 */ + CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP216]), /* SCIFB2 */ + CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP202]), /* SCIFA2 */ + CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP721]), /* SCIF0 */ + CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP720]), /* SCIF1 */ + CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP719]), /* SCIF2 */ + CLKDEV_DEV_ID("sh-sci.9", &mstp_clks[MSTP718]), /* SCIF3 */ + CLKDEV_DEV_ID("sh-sci.10", &mstp_clks[MSTP715]), /* SCIF4 */ + CLKDEV_DEV_ID("sh-sci.11", &mstp_clks[MSTP714]), /* SCIF5 */ + CLKDEV_DEV_ID("sh-sci.12", &mstp_clks[MSTP1105]), /* SCIFA3 */ + CLKDEV_DEV_ID("sh-sci.13", &mstp_clks[MSTP1106]), /* SCIFA4 */ + CLKDEV_DEV_ID("sh-sci.14", &mstp_clks[MSTP1107]), /* SCIFA5 */ }; #define R8A7791_CLOCK_ROOT(e, m, p0, p1, p30, p31) \ diff --git a/arch/arm/mach-shmobile/include/mach/r8a7791.h b/arch/arm/mach-shmobile/include/mach/r8a7791.h index 43b7206998da..d234b8cd9e91 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7791.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7791.h @@ -1,6 +1,7 @@ #ifndef __ASM_R8A7791_H__ #define __ASM_R8A7791_H__ +void r8a7791_add_dt_devices(void); void r8a7791_clock_init(void); #endif /* __ASM_R8A7791_H__ */ diff --git a/arch/arm/mach-shmobile/setup-r8a7791.c b/arch/arm/mach-shmobile/setup-r8a7791.c index 88dcce1a6391..0de6aec3bb63 100644 --- a/arch/arm/mach-shmobile/setup-r8a7791.c +++ b/arch/arm/mach-shmobile/setup-r8a7791.c @@ -22,10 +22,92 @@ #include #include #include +#include #include +#include #include #include +#define SCIF_COMMON(scif_type, baseaddr, irq) \ + .type = scif_type, \ + .mapbase = baseaddr, \ + .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, \ + .irqs = SCIx_IRQ_MUXED(irq) + +#define SCIFA_DATA(index, baseaddr, irq) \ +[index] = { \ + SCIF_COMMON(PORT_SCIFA, baseaddr, irq), \ + .scbrr_algo_id = SCBRR_ALGO_4, \ + .scscr = SCSCR_RE | SCSCR_TE, \ +} + +#define SCIFB_DATA(index, baseaddr, irq) \ +[index] = { \ + SCIF_COMMON(PORT_SCIFB, baseaddr, irq), \ + .scbrr_algo_id = SCBRR_ALGO_4, \ + .scscr = SCSCR_RE | SCSCR_TE, \ +} + +#define SCIF_DATA(index, baseaddr, irq) \ +[index] = { \ + SCIF_COMMON(PORT_SCIF, baseaddr, irq), \ + .scbrr_algo_id = SCBRR_ALGO_2, \ + .scscr = SCSCR_RE | SCSCR_TE, \ +} + +#define HSCIF_DATA(index, baseaddr, irq) \ +[index] = { \ + SCIF_COMMON(PORT_HSCIF, baseaddr, irq), \ + .scbrr_algo_id = SCBRR_ALGO_6, \ + .scscr = SCSCR_RE | SCSCR_TE, \ +} + +enum { SCIFA0, SCIFA1, SCIFB0, SCIFB1, SCIFB2, SCIFA2, SCIF0, SCIF1, + SCIF2, SCIF3, SCIF4, SCIF5, SCIFA3, SCIFA4, SCIFA5 }; + +static const struct plat_sci_port scif[] __initconst = { + SCIFA_DATA(SCIFA0, 0xe6c40000, gic_spi(144)), /* SCIFA0 */ + SCIFA_DATA(SCIFA1, 0xe6c50000, gic_spi(145)), /* SCIFA1 */ + SCIFB_DATA(SCIFB0, 0xe6c20000, gic_spi(148)), /* SCIFB0 */ + SCIFB_DATA(SCIFB1, 0xe6c30000, gic_spi(149)), /* SCIFB1 */ + SCIFB_DATA(SCIFB2, 0xe6ce0000, gic_spi(150)), /* SCIFB2 */ + SCIFA_DATA(SCIFA2, 0xe6c60000, gic_spi(151)), /* SCIFA2 */ + SCIF_DATA(SCIF0, 0xe6e60000, gic_spi(152)), /* SCIF0 */ + SCIF_DATA(SCIF1, 0xe6e68000, gic_spi(153)), /* SCIF1 */ + SCIF_DATA(SCIF2, 0xe6e58000, gic_spi(22)), /* SCIF2 */ + SCIF_DATA(SCIF3, 0xe6ea8000, gic_spi(23)), /* SCIF3 */ + SCIF_DATA(SCIF4, 0xe6ee0000, gic_spi(24)), /* SCIF4 */ + SCIF_DATA(SCIF5, 0xe6ee8000, gic_spi(25)), /* SCIF5 */ + SCIFA_DATA(SCIFA3, 0xe6c70000, gic_spi(29)), /* SCIFA3 */ + SCIFA_DATA(SCIFA4, 0xe6c78000, gic_spi(30)), /* SCIFA4 */ + SCIFA_DATA(SCIFA5, 0xe6c80000, gic_spi(31)), /* SCIFA5 */ +}; + +static inline void r8a7791_register_scif(int idx) +{ + platform_device_register_data(&platform_bus, "sh-sci", idx, &scif[idx], + sizeof(struct plat_sci_port)); +} + +void __init r8a7791_add_dt_devices(void) +{ + r8a7791_register_scif(SCIFA0); + r8a7791_register_scif(SCIFA1); + r8a7791_register_scif(SCIFB0); + r8a7791_register_scif(SCIFB1); + r8a7791_register_scif(SCIFB2); + r8a7791_register_scif(SCIFA2); + r8a7791_register_scif(SCIF0); + r8a7791_register_scif(SCIF1); + r8a7791_register_scif(SCIF2); + r8a7791_register_scif(SCIF3); + r8a7791_register_scif(SCIF4); + r8a7791_register_scif(SCIF5); + r8a7791_register_scif(SCIFA3); + r8a7791_register_scif(SCIFA4); + r8a7791_register_scif(SCIFA5); +} + #ifdef CONFIG_USE_OF static const char *r8a7791_boards_compat_dt[] __initdata = { "renesas,r8a7791", -- cgit v1.2.3 From 1bebd72a71e4ea1e9f68a9e71faee724c5e8f903 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 4 Sep 2013 12:46:17 +0900 Subject: ARM: shmobile: r8a7791 CMT support Add r8a7791 CMT support via channel 0 of CMT0. At this point the CMT is used for clock event operation, but in the future the arch timer will be the main timer and the CMT will be used for deep sleep wake up only. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman (cherry picked from commit a7663b88280d00359715817620798e99d54d401c) Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/clock-r8a7791.c | 7 ++++++- arch/arm/mach-shmobile/include/mach/r8a7791.h | 1 + arch/arm/mach-shmobile/setup-r8a7791.c | 29 +++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-shmobile/include') diff --git a/arch/arm/mach-shmobile/clock-r8a7791.c b/arch/arm/mach-shmobile/clock-r8a7791.c index df3122ea4c69..c9a26f16ce5b 100644 --- a/arch/arm/mach-shmobile/clock-r8a7791.c +++ b/arch/arm/mach-shmobile/clock-r8a7791.c @@ -101,7 +101,7 @@ SH_FIXED_RATIO_CLK_SET(cp_clk, extal_clk, 1, 2); SH_FIXED_RATIO_CLK_SET(pll1_div2_clk, pll1_clk, 1, 2); SH_FIXED_RATIO_CLK_SET(hp_clk, pll1_clk, 1, 12); SH_FIXED_RATIO_CLK_SET(p_clk, pll1_clk, 1, 24); - +SH_FIXED_RATIO_CLK_SET(rclk_clk, pll1_clk, 1, (48 * 1024)); SH_FIXED_RATIO_CLK_SET(mp_clk, pll1_div2_clk, 1, 15); static struct clk *main_clks[] = { @@ -113,6 +113,7 @@ static struct clk *main_clks[] = { &pll3_clk, &hp_clk, &p_clk, + &rclk_clk, &mp_clk, &cp_clk, }; @@ -123,6 +124,7 @@ enum { MSTP719, MSTP718, MSTP715, MSTP714, MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP1105, MSTP1106, MSTP1107, + MSTP124, MSTP_NR }; @@ -142,6 +144,7 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP1105] = SH_CLK_MSTP32(&mp_clk, SMSTPCR11, 5, 0), /* SCIFA3 */ [MSTP1106] = SH_CLK_MSTP32(&mp_clk, SMSTPCR11, 6, 0), /* SCIFA4 */ [MSTP1107] = SH_CLK_MSTP32(&mp_clk, SMSTPCR11, 7, 0), /* SCIFA5 */ + [MSTP124] = SH_CLK_MSTP32(&rclk_clk, SMSTPCR1, 24, 0), /* CMT0 */ }; static struct clk_lookup lookups[] = { @@ -155,6 +158,7 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("pll3", &pll3_clk), CLKDEV_CON_ID("hp", &hp_clk), CLKDEV_CON_ID("p", &p_clk), + CLKDEV_CON_ID("rclk", &rclk_clk), CLKDEV_CON_ID("mp", &mp_clk), CLKDEV_CON_ID("cp", &cp_clk), CLKDEV_CON_ID("peripheral_clk", &hp_clk), @@ -175,6 +179,7 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("sh-sci.12", &mstp_clks[MSTP1105]), /* SCIFA3 */ CLKDEV_DEV_ID("sh-sci.13", &mstp_clks[MSTP1106]), /* SCIFA4 */ CLKDEV_DEV_ID("sh-sci.14", &mstp_clks[MSTP1107]), /* SCIFA5 */ + CLKDEV_DEV_ID("sh_cmt.0", &mstp_clks[MSTP124]), }; #define R8A7791_CLOCK_ROOT(e, m, p0, p1, p30, p31) \ diff --git a/arch/arm/mach-shmobile/include/mach/r8a7791.h b/arch/arm/mach-shmobile/include/mach/r8a7791.h index d234b8cd9e91..2e6d66131083 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7791.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7791.h @@ -3,5 +3,6 @@ void r8a7791_add_dt_devices(void); void r8a7791_clock_init(void); +void r8a7791_init_early(void); #endif /* __ASM_R8A7791_H__ */ diff --git a/arch/arm/mach-shmobile/setup-r8a7791.c b/arch/arm/mach-shmobile/setup-r8a7791.c index 0de6aec3bb63..b56399d2e1de 100644 --- a/arch/arm/mach-shmobile/setup-r8a7791.c +++ b/arch/arm/mach-shmobile/setup-r8a7791.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -89,6 +90,25 @@ static inline void r8a7791_register_scif(int idx) sizeof(struct plat_sci_port)); } +static const struct sh_timer_config cmt00_platform_data __initconst = { + .name = "CMT00", + .timer_bit = 0, + .clockevent_rating = 80, +}; + +static const struct resource cmt00_resources[] __initconst = { + DEFINE_RES_MEM(0xffca0510, 0x0c), + DEFINE_RES_MEM(0xffca0500, 0x04), + DEFINE_RES_IRQ(gic_spi(142)), /* CMT0_0 */ +}; + +#define r8a7791_register_cmt(idx) \ + platform_device_register_resndata(&platform_bus, "sh_cmt", \ + idx, cmt##idx##_resources, \ + ARRAY_SIZE(cmt##idx##_resources), \ + &cmt##idx##_platform_data, \ + sizeof(struct sh_timer_config)) + void __init r8a7791_add_dt_devices(void) { r8a7791_register_scif(SCIFA0); @@ -106,6 +126,14 @@ void __init r8a7791_add_dt_devices(void) r8a7791_register_scif(SCIFA3); r8a7791_register_scif(SCIFA4); r8a7791_register_scif(SCIFA5); + r8a7791_register_cmt(00); +} + +void __init r8a7791_init_early(void) +{ +#ifndef CONFIG_ARM_ARCH_TIMER + shmobile_setup_delay(1300, 2, 4); /* Cortex-A15 @ 1300MHz */ +#endif } #ifdef CONFIG_USE_OF @@ -115,6 +143,7 @@ static const char *r8a7791_boards_compat_dt[] __initdata = { }; DT_MACHINE_START(R8A7791_DT, "Generic R8A7791 (Flattened Device Tree)") + .init_early = r8a7791_init_early, .dt_compat = r8a7791_boards_compat_dt, MACHINE_END #endif /* CONFIG_USE_OF */ -- cgit v1.2.3 From f39d35fcc2cd7a24ec3128adffd7876953999e1f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Sun, 4 Aug 2013 17:43:01 -0700 Subject: ARM: shmobile: r8a7778: add usb phy power control function USB phy initialisation function is needed from not only USB Host but also USB Function too. This patch adds usb phy common control function. Signed-off-by: Kuninori Morimoto Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/include/mach/r8a7778.h | 2 ++ arch/arm/mach-shmobile/setup-r8a7778.c | 37 +++++++++++++++++++-------- 2 files changed, 28 insertions(+), 11 deletions(-) (limited to 'arch/arm/mach-shmobile/include') diff --git a/arch/arm/mach-shmobile/include/mach/r8a7778.h b/arch/arm/mach-shmobile/include/mach/r8a7778.h index adfcf51b163d..ea1dca6880f4 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7778.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7778.h @@ -35,4 +35,6 @@ extern void r8a7778_clock_init(void); extern void r8a7778_init_irq_extpin(int irlm); extern void r8a7778_pinmux_init(void); +extern int r8a7778_usb_phy_power(bool enable); + #endif /* __ASM_R8A7778_H__ */ diff --git a/arch/arm/mach-shmobile/setup-r8a7778.c b/arch/arm/mach-shmobile/setup-r8a7778.c index 6a2657ebd197..e484d1420a01 100644 --- a/arch/arm/mach-shmobile/setup-r8a7778.c +++ b/arch/arm/mach-shmobile/setup-r8a7778.c @@ -95,29 +95,46 @@ static struct sh_timer_config sh_tmu1_platform_data __initdata = { &sh_tmu##idx##_platform_data, \ sizeof(sh_tmu##idx##_platform_data)) -/* USB */ -static struct usb_phy *phy; +int r8a7778_usb_phy_power(bool enable) +{ + static struct usb_phy *phy = NULL; + int ret = 0; + + if (!phy) + phy = usb_get_phy(USB_PHY_TYPE_USB2); + + if (IS_ERR(phy)) { + pr_err("kernel doesn't have usb phy driver\n"); + return PTR_ERR(phy); + } + + if (enable) + ret = usb_phy_init(phy); + else + usb_phy_shutdown(phy); + return ret; +} + +/* USB */ static int usb_power_on(struct platform_device *pdev) { - if (IS_ERR(phy)) - return PTR_ERR(phy); + int ret = r8a7778_usb_phy_power(true); + + if (ret) + return ret; pm_runtime_enable(&pdev->dev); pm_runtime_get_sync(&pdev->dev); - usb_phy_init(phy); - return 0; } static void usb_power_off(struct platform_device *pdev) { - if (IS_ERR(phy)) + if (r8a7778_usb_phy_power(false)) return; - usb_phy_shutdown(phy); - pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); } @@ -353,8 +370,6 @@ void __init r8a7778_add_standard_devices(void) void __init r8a7778_init_late(void) { - phy = usb_get_phy(USB_PHY_TYPE_USB2); - platform_device_register_full(&ehci_info); platform_device_register_full(&ohci_info); } -- cgit v1.2.3 From a112de8c7ae231f396e28160e84d0eab3a79dffc Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 29 Aug 2013 08:21:58 +0900 Subject: ARM: shmobile: Shared APMU SMP support code without DT Introduce shared APMU SMP code for mach-shmobile. Both SMP boot up and CPU Hotplug is supported. This version does not use DT but if needed this will be added as an incremental feature patch. The code is designed around CONFIG_NR_CPUS and should in theory support any number of APMUs, however due to the current DT-less static design only a single APMU is supported. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/include/mach/common.h | 6 + arch/arm/mach-shmobile/platsmp-apmu.c | 178 +++++++++++++++++++++++++++ 2 files changed, 184 insertions(+) create mode 100644 arch/arm/mach-shmobile/platsmp-apmu.c (limited to 'arch/arm/mach-shmobile/include') diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h index cfe397716fd1..3460bb13c988 100644 --- a/arch/arm/mach-shmobile/include/mach/common.h +++ b/arch/arm/mach-shmobile/include/mach/common.h @@ -22,6 +22,12 @@ extern int shmobile_smp_scu_boot_secondary(unsigned int cpu, struct task_struct *idle); extern void shmobile_smp_scu_cpu_die(unsigned int cpu); extern int shmobile_smp_scu_cpu_kill(unsigned int cpu); +extern void shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus); +extern int shmobile_smp_apmu_boot_secondary(unsigned int cpu, + struct task_struct *idle); +extern void shmobile_smp_apmu_cpu_die(unsigned int cpu); +extern int shmobile_smp_apmu_cpu_kill(unsigned int cpu); +extern void shmobile_invalidate_start(void); struct clk; extern int shmobile_clk_init(void); extern void shmobile_handle_irq_intc(struct pt_regs *); diff --git a/arch/arm/mach-shmobile/platsmp-apmu.c b/arch/arm/mach-shmobile/platsmp-apmu.c new file mode 100644 index 000000000000..34dc40dacb79 --- /dev/null +++ b/arch/arm/mach-shmobile/platsmp-apmu.c @@ -0,0 +1,178 @@ +/* + * SMP support for SoCs with APMU + * + * Copyright (C) 2013 Magnus Damm + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct { + void __iomem *iomem; + int bit; +} apmu_cpus[CONFIG_NR_CPUS]; + +#define WUPCR_OFFS 0x10 +#define PSTR_OFFS 0x40 +#define CPUNCR_OFFS(n) (0x100 + (0x10 * (n))) + +static int apmu_power_on(void __iomem *p, int bit) +{ + /* request power on */ + writel_relaxed(BIT(bit), p + WUPCR_OFFS); + + /* wait for APMU to finish */ + while (readl_relaxed(p + WUPCR_OFFS) != 0) + ; + + return 0; +} + +static int apmu_power_off(void __iomem *p, int bit) +{ + /* request Core Standby for next WFI */ + writel_relaxed(3, p + CPUNCR_OFFS(bit)); + return 0; +} + +static int apmu_power_off_poll(void __iomem *p, int bit) +{ + int k; + + for (k = 0; k < 1000; k++) { + if (((readl_relaxed(p + PSTR_OFFS) >> (bit * 4)) & 0x03) == 3) + return 1; + + mdelay(1); + } + + return 0; +} + +static int apmu_wrap(int cpu, int (*fn)(void __iomem *p, int cpu)) +{ + void __iomem *p = apmu_cpus[cpu].iomem; + + return p ? fn(p, apmu_cpus[cpu].bit) : -EINVAL; +} + +static void apmu_init_cpu(struct resource *res, int cpu, int bit) +{ + if (apmu_cpus[cpu].iomem) + return; + + apmu_cpus[cpu].iomem = ioremap_nocache(res->start, resource_size(res)); + apmu_cpus[cpu].bit = bit; + + pr_debug("apmu ioremap %d %d 0x%08x 0x%08x\n", cpu, bit, + res->start, resource_size(res)); +} + +static struct { + struct resource iomem; + int cpus[4]; +} apmu_config[] = { + { + .iomem = DEFINE_RES_MEM(0xe6152000, 0x88), + .cpus = { 0, 1, 2, 3 }, + } +}; + +static void apmu_parse_cfg(void (*fn)(struct resource *res, int cpu, int bit)) +{ + u32 id; + int k; + int bit, index; + + for (k = 0; k < ARRAY_SIZE(apmu_config); k++) { + for (bit = 0; bit < ARRAY_SIZE(apmu_config[k].cpus); bit++) { + id = apmu_config[k].cpus[bit]; + if (id >= 0) { + index = get_logical_index(id); + if (index >= 0) + fn(&apmu_config[k].iomem, index, bit); + } + } + } +} + +void __init shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus) +{ + /* install boot code shared by all CPUs */ + shmobile_boot_fn = virt_to_phys(shmobile_smp_boot); + shmobile_boot_arg = MPIDR_HWID_BITMASK; + + /* perform per-cpu setup */ + apmu_parse_cfg(apmu_init_cpu); +} + +int shmobile_smp_apmu_boot_secondary(unsigned int cpu, struct task_struct *idle) +{ + /* For this particular CPU register boot vector */ + shmobile_smp_hook(cpu, virt_to_phys(shmobile_invalidate_start), 0); + + return apmu_wrap(cpu, apmu_power_on); +} + +#ifdef CONFIG_HOTPLUG_CPU +/* nicked from arch/arm/mach-exynos/hotplug.c */ +static inline void cpu_enter_lowpower_a15(void) +{ + unsigned int v; + + asm volatile( + " mrc p15, 0, %0, c1, c0, 0\n" + " bic %0, %0, %1\n" + " mcr p15, 0, %0, c1, c0, 0\n" + : "=&r" (v) + : "Ir" (CR_C) + : "cc"); + + flush_cache_louis(); + + asm volatile( + /* + * Turn off coherency + */ + " mrc p15, 0, %0, c1, c0, 1\n" + " bic %0, %0, %1\n" + " mcr p15, 0, %0, c1, c0, 1\n" + : "=&r" (v) + : "Ir" (0x40) + : "cc"); + + isb(); + dsb(); +} + +void shmobile_smp_apmu_cpu_die(unsigned int cpu) +{ + /* For this particular CPU deregister boot vector */ + shmobile_smp_hook(cpu, 0, 0); + + /* Select next sleep mode using the APMU */ + apmu_wrap(cpu, apmu_power_off); + + /* Do ARM specific CPU shutdown */ + cpu_enter_lowpower_a15(); + + /* jump to shared mach-shmobile sleep / reset code */ + shmobile_smp_sleep(); +} + +int shmobile_smp_apmu_cpu_kill(unsigned int cpu) +{ + return apmu_wrap(cpu, apmu_power_off_poll); +} +#endif -- cgit v1.2.3 From ad09cb83811b228eb6f98230d307bb837e6a758f Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 29 Aug 2013 08:22:07 +0900 Subject: ARM: shmobile: Add r8a7790 SMP support using APMU code Add r8a7790 SMP support using the shared APMU code. To enable SMP the r8a7790 specific DTS needs to be updated to include CPU cores, and this is happening in a separate patch. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/Makefile | 1 + arch/arm/mach-shmobile/board-lager-reference.c | 1 + arch/arm/mach-shmobile/board-lager.c | 1 + arch/arm/mach-shmobile/include/mach/r8a7790.h | 1 + arch/arm/mach-shmobile/setup-r8a7790.c | 1 + arch/arm/mach-shmobile/smp-r8a7790.c | 67 ++++++++++++++++++++++++++ 6 files changed, 72 insertions(+) create mode 100644 arch/arm/mach-shmobile/smp-r8a7790.c (limited to 'arch/arm/mach-shmobile/include') diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index 2705bfa8c113..381fc97ef0f5 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile @@ -34,6 +34,7 @@ endif smp-y := platsmp.o headsmp.o smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o headsmp-scu.o platsmp-scu.o smp-$(CONFIG_ARCH_R8A7779) += smp-r8a7779.o headsmp-scu.o platsmp-scu.o +smp-$(CONFIG_ARCH_R8A7790) += smp-r8a7790.o platsmp-apmu.o smp-$(CONFIG_ARCH_EMEV2) += smp-emev2.o headsmp-scu.o platsmp-scu.o # IRQ objects diff --git a/arch/arm/mach-shmobile/board-lager-reference.c b/arch/arm/mach-shmobile/board-lager-reference.c index 2856f51ff8a6..d39a91b3ba48 100644 --- a/arch/arm/mach-shmobile/board-lager-reference.c +++ b/arch/arm/mach-shmobile/board-lager-reference.c @@ -38,6 +38,7 @@ static const char *lager_boards_compat_dt[] __initdata = { }; DT_MACHINE_START(LAGER_DT, "lager") + .smp = smp_ops(r8a7790_smp_ops), .init_early = r8a7790_init_early, .init_machine = lager_add_standard_devices, .init_time = r8a7790_timer_init, diff --git a/arch/arm/mach-shmobile/board-lager.c b/arch/arm/mach-shmobile/board-lager.c index 4047fac811c0..ef3baaa79e6d 100644 --- a/arch/arm/mach-shmobile/board-lager.c +++ b/arch/arm/mach-shmobile/board-lager.c @@ -161,6 +161,7 @@ static const char *lager_boards_compat_dt[] __initdata = { }; DT_MACHINE_START(LAGER_DT, "lager") + .smp = smp_ops(r8a7790_smp_ops), .init_early = r8a7790_init_early, .init_time = r8a7790_timer_init, .init_machine = lager_add_standard_devices, diff --git a/arch/arm/mach-shmobile/include/mach/r8a7790.h b/arch/arm/mach-shmobile/include/mach/r8a7790.h index 177a8372abb7..79e731c83e50 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7790.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7790.h @@ -7,6 +7,7 @@ void r8a7790_clock_init(void); void r8a7790_pinmux_init(void); void r8a7790_init_early(void); void r8a7790_timer_init(void); +extern struct smp_operations r8a7790_smp_ops; #define MD(nr) BIT(nr) u32 r8a7790_read_mode_pins(void); diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c index e0d29a265c2d..c7e24eff9ba2 100644 --- a/arch/arm/mach-shmobile/setup-r8a7790.c +++ b/arch/arm/mach-shmobile/setup-r8a7790.c @@ -283,6 +283,7 @@ static const char * const r8a7790_boards_compat_dt[] __initconst = { }; DT_MACHINE_START(R8A7790_DT, "Generic R8A7790 (Flattened Device Tree)") + .smp = smp_ops(r8a7790_smp_ops), .init_early = r8a7790_init_early, .init_time = r8a7790_timer_init, .dt_compat = r8a7790_boards_compat_dt, diff --git a/arch/arm/mach-shmobile/smp-r8a7790.c b/arch/arm/mach-shmobile/smp-r8a7790.c new file mode 100644 index 000000000000..015e2753de1f --- /dev/null +++ b/arch/arm/mach-shmobile/smp-r8a7790.c @@ -0,0 +1,67 @@ +/* + * SMP support for r8a7790 + * + * Copyright (C) 2012-2013 Renesas Solutions Corp. + * Copyright (C) 2012 Takashi Yoshii + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include + +#define RST 0xe6160000 +#define CA15BAR 0x0020 +#define CA7BAR 0x0030 +#define CA15RESCNT 0x0040 +#define CA7RESCNT 0x0044 +#define MERAM 0xe8080000 + +static void __init r8a7790_smp_prepare_cpus(unsigned int max_cpus) +{ + void __iomem *p; + u32 bar; + + /* let APMU code install data related to shmobile_boot_vector */ + shmobile_smp_apmu_prepare_cpus(max_cpus); + + /* MERAM for jump stub, because BAR requires 256KB aligned address */ + p = ioremap_nocache(MERAM, shmobile_boot_size); + memcpy_toio(p, shmobile_boot_vector, shmobile_boot_size); + iounmap(p); + + /* setup reset vectors */ + p = ioremap_nocache(RST, 0x63); + bar = (MERAM >> 8) & 0xfffffc00; + writel_relaxed(bar, p + CA15BAR); + writel_relaxed(bar, p + CA7BAR); + writel_relaxed(bar | 0x10, p + CA15BAR); + writel_relaxed(bar | 0x10, p + CA7BAR); + + /* enable clocks to all CPUs */ + writel_relaxed((readl_relaxed(p + CA15RESCNT) & ~0x0f) | 0xa5a50000, + p + CA15RESCNT); + writel_relaxed((readl_relaxed(p + CA7RESCNT) & ~0x0f) | 0x5a5a0000, + p + CA7RESCNT); + iounmap(p); +} + +struct smp_operations r8a7790_smp_ops __initdata = { + .smp_prepare_cpus = r8a7790_smp_prepare_cpus, + .smp_boot_secondary = shmobile_smp_apmu_boot_secondary, +#ifdef CONFIG_HOTPLUG_CPU + .cpu_disable = shmobile_smp_cpu_disable, + .cpu_die = shmobile_smp_apmu_cpu_die, + .cpu_kill = shmobile_smp_apmu_cpu_kill, +#endif +}; -- cgit v1.2.3 From e4550216ef8245b1c9892239a2121a7b15ac2e91 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Sat, 14 Sep 2013 22:47:02 +0900 Subject: ARM: shmobile: Remove shmobile_smp_scu_boot_secondary() Remove shmobile_smp_scu_boot_secondary() since it is no longer used. CPU boot vector setup is instead handled by CPU notifiers. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/include/mach/common.h | 2 -- arch/arm/mach-shmobile/platsmp-scu.c | 8 -------- 2 files changed, 10 deletions(-) (limited to 'arch/arm/mach-shmobile/include') diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h index 3460bb13c988..e31980590eb4 100644 --- a/arch/arm/mach-shmobile/include/mach/common.h +++ b/arch/arm/mach-shmobile/include/mach/common.h @@ -18,8 +18,6 @@ extern int shmobile_smp_cpu_disable(unsigned int cpu); extern void shmobile_invalidate_start(void); extern void shmobile_boot_scu(void); extern void shmobile_smp_scu_prepare_cpus(unsigned int max_cpus); -extern int shmobile_smp_scu_boot_secondary(unsigned int cpu, - struct task_struct *idle); extern void shmobile_smp_scu_cpu_die(unsigned int cpu); extern int shmobile_smp_scu_cpu_kill(unsigned int cpu); extern void shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus); diff --git a/arch/arm/mach-shmobile/platsmp-scu.c b/arch/arm/mach-shmobile/platsmp-scu.c index 49ae8dfc625d..673ad6e80869 100644 --- a/arch/arm/mach-shmobile/platsmp-scu.c +++ b/arch/arm/mach-shmobile/platsmp-scu.c @@ -51,14 +51,6 @@ void __init shmobile_smp_scu_prepare_cpus(unsigned int max_cpus) register_cpu_notifier(&shmobile_smp_scu_notifier); } -int shmobile_smp_scu_boot_secondary(unsigned int cpu, struct task_struct *idle) -{ - /* For this particular CPU register SCU boot vector */ - shmobile_smp_hook(cpu, virt_to_phys(shmobile_boot_scu), - (unsigned long)shmobile_scu_base); - return 0; -} - #ifdef CONFIG_HOTPLUG_CPU void shmobile_smp_scu_cpu_die(unsigned int cpu) { -- cgit v1.2.3 From 9f754b4a68e53c71f55aaa9564579ae617a2ff11 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 2 Aug 2013 16:50:40 +0200 Subject: ARM: shmobile: r8a73a4: add a DMAC platform device and clock for it Add a DMAC platform device and clock definitions for it on r8a73a4. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/clock-r8a73a4.c | 4 +- arch/arm/mach-shmobile/include/mach/r8a73a4.h | 9 +++ arch/arm/mach-shmobile/setup-r8a73a4.c | 91 +++++++++++++++++++++++++++ 3 files changed, 103 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-shmobile/include') diff --git a/arch/arm/mach-shmobile/clock-r8a73a4.c b/arch/arm/mach-shmobile/clock-r8a73a4.c index 8ea5ef6c79cc..357b9bca7940 100644 --- a/arch/arm/mach-shmobile/clock-r8a73a4.c +++ b/arch/arm/mach-shmobile/clock-r8a73a4.c @@ -504,7 +504,7 @@ static struct clk div6_clks[DIV6_NR] = { /* MSTP */ enum { - MSTP217, MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, + MSTP218, MSTP217, MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, MSTP329, MSTP323, MSTP318, MSTP317, MSTP316, MSTP315, MSTP314, MSTP313, MSTP312, MSTP305, MSTP300, MSTP411, MSTP410, MSTP409, @@ -519,6 +519,7 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP207] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 7, 0), /* SCIFB1 */ [MSTP216] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 16, 0), /* SCIFB2 */ [MSTP217] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 17, 0), /* SCIFB3 */ + [MSTP218] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* DMAC */ [MSTP300] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 0, 0), /* IIC2 */ [MSTP305] = SH_CLK_MSTP32(&div6_clks[DIV6_MMC1],SMSTPCR3, 5, 0), /* MMCIF1 */ [MSTP312] = SH_CLK_MSTP32(&div6_clks[DIV6_SDHI2],SMSTPCR3, 12, 0), /* SDHI2 */ @@ -578,6 +579,7 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP207]), CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP216]), CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP217]), + CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]), CLKDEV_DEV_ID("e6520000.i2c", &mstp_clks[MSTP300]), CLKDEV_DEV_ID("sh_mmcif.1", &mstp_clks[MSTP305]), diff --git a/arch/arm/mach-shmobile/include/mach/r8a73a4.h b/arch/arm/mach-shmobile/include/mach/r8a73a4.h index 5214338a6a47..ce8bdd1d8a8a 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a73a4.h +++ b/arch/arm/mach-shmobile/include/mach/r8a73a4.h @@ -1,6 +1,15 @@ #ifndef __ASM_R8A73A4_H__ #define __ASM_R8A73A4_H__ +/* DMA slave IDs */ +enum { + SHDMA_SLAVE_INVALID, + SHDMA_SLAVE_MMCIF0_TX, + SHDMA_SLAVE_MMCIF0_RX, + SHDMA_SLAVE_MMCIF1_TX, + SHDMA_SLAVE_MMCIF1_RX, +}; + void r8a73a4_add_standard_devices(void); void r8a73a4_add_dt_devices(void); void r8a73a4_clock_init(void); diff --git a/arch/arm/mach-shmobile/setup-r8a73a4.c b/arch/arm/mach-shmobile/setup-r8a73a4.c index 53a896275cae..b0f2749071be 100644 --- a/arch/arm/mach-shmobile/setup-r8a73a4.c +++ b/arch/arm/mach-shmobile/setup-r8a73a4.c @@ -22,8 +22,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -199,12 +201,101 @@ void __init r8a73a4_add_dt_devices(void) r8a7790_register_cmt(10); } +/* DMA */ +static const struct sh_dmae_slave_config dma_slaves[] = { + { + .slave_id = SHDMA_SLAVE_MMCIF0_TX, + .addr = 0xee200034, + .chcr = CHCR_TX(XMIT_SZ_32BIT), + .mid_rid = 0xd1, + }, { + .slave_id = SHDMA_SLAVE_MMCIF0_RX, + .addr = 0xee200034, + .chcr = CHCR_RX(XMIT_SZ_32BIT), + .mid_rid = 0xd2, + }, { + .slave_id = SHDMA_SLAVE_MMCIF1_TX, + .addr = 0xee220034, + .chcr = CHCR_TX(XMIT_SZ_32BIT), + .mid_rid = 0xe1, + }, { + .slave_id = SHDMA_SLAVE_MMCIF1_RX, + .addr = 0xee220034, + .chcr = CHCR_RX(XMIT_SZ_32BIT), + .mid_rid = 0xe2, + }, +}; + +#define DMAE_CHANNEL(a, b) \ + { \ + .offset = (a) - 0x20, \ + .dmars = (a) - 0x20 + 0x40, \ + .chclr_bit = (b), \ + .chclr_offset = 0x80 - 0x20, \ + } + +static const struct sh_dmae_channel dma_channels[] = { + DMAE_CHANNEL(0x8000, 0), + DMAE_CHANNEL(0x8080, 1), + DMAE_CHANNEL(0x8100, 2), + DMAE_CHANNEL(0x8180, 3), + DMAE_CHANNEL(0x8200, 4), + DMAE_CHANNEL(0x8280, 5), + DMAE_CHANNEL(0x8300, 6), + DMAE_CHANNEL(0x8380, 7), + DMAE_CHANNEL(0x8400, 8), + DMAE_CHANNEL(0x8480, 9), + DMAE_CHANNEL(0x8500, 10), + DMAE_CHANNEL(0x8580, 11), + DMAE_CHANNEL(0x8600, 12), + DMAE_CHANNEL(0x8680, 13), + DMAE_CHANNEL(0x8700, 14), + DMAE_CHANNEL(0x8780, 15), + DMAE_CHANNEL(0x8800, 16), + DMAE_CHANNEL(0x8880, 17), + DMAE_CHANNEL(0x8900, 18), + DMAE_CHANNEL(0x8980, 19), +}; + +static const struct sh_dmae_pdata dma_pdata = { + .slave = dma_slaves, + .slave_num = ARRAY_SIZE(dma_slaves), + .channel = dma_channels, + .channel_num = ARRAY_SIZE(dma_channels), + .ts_low_shift = TS_LOW_SHIFT, + .ts_low_mask = TS_LOW_BIT << TS_LOW_SHIFT, + .ts_high_shift = TS_HI_SHIFT, + .ts_high_mask = TS_HI_BIT << TS_HI_SHIFT, + .ts_shift = dma_ts_shift, + .ts_shift_num = ARRAY_SIZE(dma_ts_shift), + .dmaor_init = DMAOR_DME, + .chclr_present = 1, + .chclr_bitwise = 1, +}; + +static struct resource dma_resources[] = { + DEFINE_RES_MEM(0xe6700020, 0x89e0), + DEFINE_RES_IRQ_NAMED(gic_spi(220), "error_irq"), + { + /* IRQ for channels 0-19 */ + .start = gic_spi(200), + .end = gic_spi(219), + .flags = IORESOURCE_IRQ, + }, +}; + +#define r8a73a4_register_dmac() \ + platform_device_register_resndata(&platform_bus, "sh-dma-engine", 0, \ + dma_resources, ARRAY_SIZE(dma_resources), \ + &dma_pdata, sizeof(dma_pdata)) + void __init r8a73a4_add_standard_devices(void) { r8a73a4_add_dt_devices(); r8a73a4_register_irqc(0); r8a73a4_register_irqc(1); r8a73a4_register_thermal(); + r8a73a4_register_dmac(); } void __init r8a73a4_init_early(void) -- cgit v1.2.3 From 338c4991ed350abd7c5b3cb807fe022cb712a8ba Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Sun, 25 Aug 2013 01:35:13 +0400 Subject: ARM: shmobile: r8a7778: add HPB-DMAC support Add HPB-DMAC platform device on R8A7778 SoC along with its slave and channel configurations (only for SDHI0 so far). Signed-off-by: Max Filippov [Sergei: moved *enum* declaring HPB-DMAC slave IDs from now removed to , removed #include from setup-r8a7778.c, removed SSI-related *enum* values and SSI-related data from hpb_dmae_slaves[] and hpb_dmae_channels[], moved the comments after the element initializers of hpb_dmae_channels[].] Signed-off-by: Sergei Shtylyov Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/include/mach/r8a7778.h | 8 +++ arch/arm/mach-shmobile/setup-r8a7778.c | 85 +++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) (limited to 'arch/arm/mach-shmobile/include') diff --git a/arch/arm/mach-shmobile/include/mach/r8a7778.h b/arch/arm/mach-shmobile/include/mach/r8a7778.h index ea1dca6880f4..1d6fe973e8b4 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7778.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7778.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2013 Renesas Solutions Corp. * Copyright (C) 2013 Kuninori Morimoto + * Copyright (C) 2013 Cogent Embedded, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,6 +22,13 @@ #include #include +/* HPB-DMA slave IDs */ +enum { + HPBDMA_SLAVE_DUMMY, + HPBDMA_SLAVE_SDHI0_TX, + HPBDMA_SLAVE_SDHI0_RX, +}; + extern void r8a7778_add_standard_devices(void); extern void r8a7778_add_standard_devices_dt(void); extern void r8a7778_add_ether_device(struct sh_eth_plat_data *pdata); diff --git a/arch/arm/mach-shmobile/setup-r8a7778.c b/arch/arm/mach-shmobile/setup-r8a7778.c index e484d1420a01..fa1b7e44a973 100644 --- a/arch/arm/mach-shmobile/setup-r8a7778.c +++ b/arch/arm/mach-shmobile/setup-r8a7778.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -356,6 +357,88 @@ void __init r8a7778_add_dt_devices(void) r8a7778_register_tmu(1); } +/* HPB-DMA */ + +/* Asynchronous mode register (ASYNCMDR) bits */ +#define HPB_DMAE_ASYNCMDR_ASMD22_MASK BIT(2) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD22_SINGLE BIT(2) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD22_MULTI 0 /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD21_MASK BIT(1) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD21_SINGLE BIT(1) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD21_MULTI 0 /* SDHI0 */ + +static const struct hpb_dmae_slave_config hpb_dmae_slaves[] = { + { + .id = HPBDMA_SLAVE_SDHI0_TX, + .addr = 0xffe4c000 + 0x30, + .dcr = HPB_DMAE_DCR_SPDS_16BIT | + HPB_DMAE_DCR_DMDL | + HPB_DMAE_DCR_DPDS_16BIT, + .rstr = HPB_DMAE_ASYNCRSTR_ASRST21 | + HPB_DMAE_ASYNCRSTR_ASRST22 | + HPB_DMAE_ASYNCRSTR_ASRST23, + .mdr = HPB_DMAE_ASYNCMDR_ASMD21_MULTI, + .mdm = HPB_DMAE_ASYNCMDR_ASMD21_MASK, + .port = 0x0D0C, + .flags = HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE, + .dma_ch = 21, + }, { + .id = HPBDMA_SLAVE_SDHI0_RX, + .addr = 0xffe4c000 + 0x30, + .dcr = HPB_DMAE_DCR_SMDL | + HPB_DMAE_DCR_SPDS_16BIT | + HPB_DMAE_DCR_DPDS_16BIT, + .rstr = HPB_DMAE_ASYNCRSTR_ASRST21 | + HPB_DMAE_ASYNCRSTR_ASRST22 | + HPB_DMAE_ASYNCRSTR_ASRST23, + .mdr = HPB_DMAE_ASYNCMDR_ASMD22_MULTI, + .mdm = HPB_DMAE_ASYNCMDR_ASMD22_MASK, + .port = 0x0D0C, + .flags = HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE, + .dma_ch = 22, + }, +}; + +static const struct hpb_dmae_channel hpb_dmae_channels[] = { + HPB_DMAE_CHANNEL(0x7e, HPBDMA_SLAVE_SDHI0_TX), /* ch. 21 */ + HPB_DMAE_CHANNEL(0x7e, HPBDMA_SLAVE_SDHI0_RX), /* ch. 22 */ +}; + +static struct hpb_dmae_pdata dma_platform_data __initdata = { + .slaves = hpb_dmae_slaves, + .num_slaves = ARRAY_SIZE(hpb_dmae_slaves), + .channels = hpb_dmae_channels, + .num_channels = ARRAY_SIZE(hpb_dmae_channels), + .ts_shift = { + [XMIT_SZ_8BIT] = 0, + [XMIT_SZ_16BIT] = 1, + [XMIT_SZ_32BIT] = 2, + }, + .num_hw_channels = 39, +}; + +static struct resource hpb_dmae_resources[] __initdata = { + /* Channel registers */ + DEFINE_RES_MEM(0xffc08000, 0x1000), + /* Common registers */ + DEFINE_RES_MEM(0xffc09000, 0x170), + /* Asynchronous reset registers */ + DEFINE_RES_MEM(0xffc00300, 4), + /* Asynchronous mode registers */ + DEFINE_RES_MEM(0xffc00400, 4), + /* IRQ for DMA channels */ + DEFINE_RES_NAMED(gic_iid(0x7b), 5, NULL, IORESOURCE_IRQ), +}; + +static void __init r8a7778_register_hpb_dmae(void) +{ + platform_device_register_resndata(&platform_bus, "hpb-dma-engine", -1, + hpb_dmae_resources, + ARRAY_SIZE(hpb_dmae_resources), + &dma_platform_data, + sizeof(dma_platform_data)); +} + void __init r8a7778_add_standard_devices(void) { r8a7778_add_dt_devices(); @@ -366,6 +449,8 @@ void __init r8a7778_add_standard_devices(void) r8a7778_register_hspi(0); r8a7778_register_hspi(1); r8a7778_register_hspi(2); + + r8a7778_register_hpb_dmae(); } void __init r8a7778_init_late(void) -- cgit v1.2.3 From 441f750236f3d3d435a1e89ad885ec896832b9c6 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Sun, 25 Aug 2013 21:46:23 +0400 Subject: ARM: shmobile: r8a7779: add HPB-DMAC support Add HPB-DMAC platform device on R8A7779 SoC along with its slave and channel configurations (only for SDHI0 so far). Signed-off-by: Max Filippov [Sergei: moved *enum* declaring HPB-DMAC slave IDs from now removed to , removed #include from setup-r8a7779.c, removed SSI-related *enum* values and SSI-related data from hpb_dmae_slaves[] and hpb_dmae_channels[], added ASYNCMDR.ASBTMD{20|24|43} and ASYNCMDR.ASMD{20|24|43} fields/values, fixed comments to ASYNCMDR.ASBTMD2[123] and ASYNCMDR.ASMD2[123] fields/values, renamed all the bit/field/value #define's to include 'HBP_DMAE_' prefix to match the driver, moved comments after the element initializers of hpb_dmae_channels[].] Signed-off-by: Sergei Shtylyov Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/include/mach/r8a7779.h | 7 ++ arch/arm/mach-shmobile/setup-r8a7779.c | 154 ++++++++++++++++++++++++++ 2 files changed, 161 insertions(+) (limited to 'arch/arm/mach-shmobile/include') diff --git a/arch/arm/mach-shmobile/include/mach/r8a7779.h b/arch/arm/mach-shmobile/include/mach/r8a7779.h index 11c740047e14..31e87b92a9c3 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7779.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7779.h @@ -6,6 +6,13 @@ #include #include +/* HPB-DMA slave IDs */ +enum { + HPBDMA_SLAVE_DUMMY, + HPBDMA_SLAVE_SDHI0_TX, + HPBDMA_SLAVE_SDHI0_RX, +}; + struct platform_device; struct r8a7779_pm_ch { diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c index ecd0148ee1e1..eacb2f783693 100644 --- a/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/arch/arm/mach-shmobile/setup-r8a7779.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -632,6 +633,158 @@ static struct platform_device_info *vin_info_table[] __initdata = { &vin3_info, }; +/* HPB-DMA */ + +/* Asynchronous mode register bits */ +#define HPB_DMAE_ASYNCMDR_ASMD43_MASK BIT(23) /* MMC1 */ +#define HPB_DMAE_ASYNCMDR_ASMD43_SINGLE BIT(23) /* MMC1 */ +#define HPB_DMAE_ASYNCMDR_ASMD43_MULTI 0 /* MMC1 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD43_MASK BIT(22) /* MMC1 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD43_BURST BIT(22) /* MMC1 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD43_NBURST 0 /* MMC1 */ +#define HPB_DMAE_ASYNCMDR_ASMD24_MASK BIT(21) /* MMC0 */ +#define HPB_DMAE_ASYNCMDR_ASMD24_SINGLE BIT(21) /* MMC0 */ +#define HPB_DMAE_ASYNCMDR_ASMD24_MULTI 0 /* MMC0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD24_MASK BIT(20) /* MMC0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD24_BURST BIT(20) /* MMC0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD24_NBURST 0 /* MMC0 */ +#define HPB_DMAE_ASYNCMDR_ASMD41_MASK BIT(19) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD41_SINGLE BIT(19) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD41_MULTI 0 /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD41_MASK BIT(18) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD41_BURST BIT(18) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD41_NBURST 0 /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD40_MASK BIT(17) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD40_SINGLE BIT(17) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD40_MULTI 0 /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD40_MASK BIT(16) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD40_BURST BIT(16) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD40_NBURST 0 /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD39_MASK BIT(15) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD39_SINGLE BIT(15) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD39_MULTI 0 /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD39_MASK BIT(14) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD39_BURST BIT(14) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD39_NBURST 0 /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD27_MASK BIT(13) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD27_SINGLE BIT(13) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD27_MULTI 0 /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD27_MASK BIT(12) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD27_BURST BIT(12) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD27_NBURST 0 /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD26_MASK BIT(11) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD26_SINGLE BIT(11) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD26_MULTI 0 /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD26_MASK BIT(10) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD26_BURST BIT(10) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD26_NBURST 0 /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD25_MASK BIT(9) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD25_SINGLE BIT(9) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD25_MULTI 0 /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD25_MASK BIT(8) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD25_BURST BIT(8) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD25_NBURST 0 /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD23_MASK BIT(7) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD23_SINGLE BIT(7) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD23_MULTI 0 /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD23_MASK BIT(6) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD23_BURST BIT(6) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD23_NBURST 0 /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD22_MASK BIT(5) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD22_SINGLE BIT(5) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD22_MULTI 0 /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD22_MASK BIT(4) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD22_BURST BIT(4) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD22_NBURST 0 /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD21_MASK BIT(3) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD21_SINGLE BIT(3) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD21_MULTI 0 /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD21_MASK BIT(2) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD21_BURST BIT(2) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD21_NBURST 0 /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD20_MASK BIT(1) /* SDHI1 */ +#define HPB_DMAE_ASYNCMDR_ASMD20_SINGLE BIT(1) /* SDHI1 */ +#define HPB_DMAE_ASYNCMDR_ASMD20_MULTI 0 /* SDHI1 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD20_MASK BIT(0) /* SDHI1 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD20_BURST BIT(0) /* SDHI1 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD20_NBURST 0 /* SDHI1 */ + +static const struct hpb_dmae_slave_config hpb_dmae_slaves[] = { + { + .id = HPBDMA_SLAVE_SDHI0_TX, + .addr = 0xffe4c000 + 0x30, + .dcr = HPB_DMAE_DCR_SPDS_16BIT | + HPB_DMAE_DCR_DMDL | + HPB_DMAE_DCR_DPDS_16BIT, + .rstr = HPB_DMAE_ASYNCRSTR_ASRST21 | + HPB_DMAE_ASYNCRSTR_ASRST22 | + HPB_DMAE_ASYNCRSTR_ASRST23, + .mdr = HPB_DMAE_ASYNCMDR_ASMD21_SINGLE | + HPB_DMAE_ASYNCMDR_ASBTMD21_NBURST, + .mdm = HPB_DMAE_ASYNCMDR_ASMD21_MASK | + HPB_DMAE_ASYNCMDR_ASBTMD21_MASK, + .port = 0x0D0C, + .flags = HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE, + .dma_ch = 21, + }, { + .id = HPBDMA_SLAVE_SDHI0_RX, + .addr = 0xffe4c000 + 0x30, + .dcr = HPB_DMAE_DCR_SMDL | + HPB_DMAE_DCR_SPDS_16BIT | + HPB_DMAE_DCR_DPDS_16BIT, + .rstr = HPB_DMAE_ASYNCRSTR_ASRST21 | + HPB_DMAE_ASYNCRSTR_ASRST22 | + HPB_DMAE_ASYNCRSTR_ASRST23, + .mdr = HPB_DMAE_ASYNCMDR_ASMD22_SINGLE | + HPB_DMAE_ASYNCMDR_ASBTMD22_NBURST, + .mdm = HPB_DMAE_ASYNCMDR_ASMD22_MASK | + HPB_DMAE_ASYNCMDR_ASBTMD22_MASK, + .port = 0x0D0C, + .flags = HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE, + .dma_ch = 22, + }, +}; + +static const struct hpb_dmae_channel hpb_dmae_channels[] = { + HPB_DMAE_CHANNEL(0x93, HPBDMA_SLAVE_SDHI0_TX), /* ch. 21 */ + HPB_DMAE_CHANNEL(0x93, HPBDMA_SLAVE_SDHI0_RX), /* ch. 22 */ +}; + +static struct hpb_dmae_pdata dma_platform_data __initdata = { + .slaves = hpb_dmae_slaves, + .num_slaves = ARRAY_SIZE(hpb_dmae_slaves), + .channels = hpb_dmae_channels, + .num_channels = ARRAY_SIZE(hpb_dmae_channels), + .ts_shift = { + [XMIT_SZ_8BIT] = 0, + [XMIT_SZ_16BIT] = 1, + [XMIT_SZ_32BIT] = 2, + }, + .num_hw_channels = 44, +}; + +static struct resource hpb_dmae_resources[] __initdata = { + /* Channel registers */ + DEFINE_RES_MEM(0xffc08000, 0x1000), + /* Common registers */ + DEFINE_RES_MEM(0xffc09000, 0x170), + /* Asynchronous reset registers */ + DEFINE_RES_MEM(0xffc00300, 4), + /* Asynchronous mode registers */ + DEFINE_RES_MEM(0xffc00400, 4), + /* IRQ for DMA channels */ + DEFINE_RES_NAMED(gic_iid(0x8e), 12, NULL, IORESOURCE_IRQ), +}; + +static void __init r8a7779_register_hpb_dmae(void) +{ + platform_device_register_resndata(&platform_bus, "hpb-dma-engine", -1, + hpb_dmae_resources, + ARRAY_SIZE(hpb_dmae_resources), + &dma_platform_data, + sizeof(dma_platform_data)); +} + static struct platform_device *r8a7779_devices_dt[] __initdata = { &scif0_device, &scif1_device, @@ -665,6 +818,7 @@ void __init r8a7779_add_standard_devices(void) ARRAY_SIZE(r8a7779_devices_dt)); platform_add_devices(r8a7779_standard_devices, ARRAY_SIZE(r8a7779_standard_devices)); + r8a7779_register_hpb_dmae(); } void __init r8a7779_add_ether_device(struct sh_eth_plat_data *pdata) -- cgit v1.2.3 From 50c517d92eac08b352ccf4b25c93a53947bb855e Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 12 Sep 2013 09:32:49 +0900 Subject: ARM: shmobile: Break out R-Car Gen2 setup code Move arch timer workaround code and boot mode pin handling from setup-r8a7790.c to setup-rcar-gen2.c. With this in place the same code can be used on other R-Car Generation 2 devices such as r8a7791. Signed-off-by: Magnus Damm [horms+renesas@verge.net.au trivial rebase of board-lager.c for introduction of lager_add_standard_devices()] Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/Makefile | 1 + arch/arm/mach-shmobile/board-lager-reference.c | 2 +- arch/arm/mach-shmobile/board-lager.c | 2 +- arch/arm/mach-shmobile/clock-r8a7790.c | 2 +- arch/arm/mach-shmobile/include/mach/r8a7790.h | 6 +- arch/arm/mach-shmobile/include/mach/rcar-gen2.h | 8 +++ arch/arm/mach-shmobile/setup-r8a7790.c | 68 +----------------- arch/arm/mach-shmobile/setup-rcar-gen2.c | 91 +++++++++++++++++++++++++ 8 files changed, 106 insertions(+), 74 deletions(-) create mode 100644 arch/arm/mach-shmobile/include/mach/rcar-gen2.h create mode 100644 arch/arm/mach-shmobile/setup-rcar-gen2.c (limited to 'arch/arm/mach-shmobile/include') diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index d30ec1a427ec..6b7a02ee8b93 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_ARCH_R8A7740) += setup-r8a7740.o obj-$(CONFIG_ARCH_R8A7778) += setup-r8a7778.o obj-$(CONFIG_ARCH_R8A7779) += setup-r8a7779.o obj-$(CONFIG_ARCH_R8A7790) += setup-r8a7790.o +obj-$(CONFIG_ARCH_R8A7790) += setup-r8a7790.o setup-rcar-gen2.o obj-$(CONFIG_ARCH_R8A7791) += setup-r8a7791.o obj-$(CONFIG_ARCH_EMEV2) += setup-emev2.o diff --git a/arch/arm/mach-shmobile/board-lager-reference.c b/arch/arm/mach-shmobile/board-lager-reference.c index d39a91b3ba48..1a1a4a888632 100644 --- a/arch/arm/mach-shmobile/board-lager-reference.c +++ b/arch/arm/mach-shmobile/board-lager-reference.c @@ -40,7 +40,7 @@ static const char *lager_boards_compat_dt[] __initdata = { DT_MACHINE_START(LAGER_DT, "lager") .smp = smp_ops(r8a7790_smp_ops), .init_early = r8a7790_init_early, + .init_time = rcar_gen2_timer_init, .init_machine = lager_add_standard_devices, - .init_time = r8a7790_timer_init, .dt_compat = lager_boards_compat_dt, MACHINE_END diff --git a/arch/arm/mach-shmobile/board-lager.c b/arch/arm/mach-shmobile/board-lager.c index 6d1026e99e13..4e040e4d1102 100644 --- a/arch/arm/mach-shmobile/board-lager.c +++ b/arch/arm/mach-shmobile/board-lager.c @@ -188,7 +188,7 @@ static const char *lager_boards_compat_dt[] __initdata = { DT_MACHINE_START(LAGER_DT, "lager") .smp = smp_ops(r8a7790_smp_ops), .init_early = r8a7790_init_early, - .init_time = r8a7790_timer_init, + .init_time = rcar_gen2_timer_init, .init_machine = lager_init, .dt_compat = lager_boards_compat_dt, MACHINE_END diff --git a/arch/arm/mach-shmobile/clock-r8a7790.c b/arch/arm/mach-shmobile/clock-r8a7790.c index 7661e898f376..a64f965c7da1 100644 --- a/arch/arm/mach-shmobile/clock-r8a7790.c +++ b/arch/arm/mach-shmobile/clock-r8a7790.c @@ -310,7 +310,7 @@ static struct clk_lookup lookups[] = { void __init r8a7790_clock_init(void) { - u32 mode = r8a7790_read_mode_pins(); + u32 mode = rcar_gen2_read_mode_pins(); int k, ret = 0; switch (mode & (MD(14) | MD(13))) { diff --git a/arch/arm/mach-shmobile/include/mach/r8a7790.h b/arch/arm/mach-shmobile/include/mach/r8a7790.h index 79e731c83e50..5fbfa28b40b6 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7790.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7790.h @@ -1,15 +1,13 @@ #ifndef __ASM_R8A7790_H__ #define __ASM_R8A7790_H__ +#include + void r8a7790_add_standard_devices(void); void r8a7790_add_dt_devices(void); void r8a7790_clock_init(void); void r8a7790_pinmux_init(void); void r8a7790_init_early(void); -void r8a7790_timer_init(void); extern struct smp_operations r8a7790_smp_ops; -#define MD(nr) BIT(nr) -u32 r8a7790_read_mode_pins(void); - #endif /* __ASM_R8A7790_H__ */ diff --git a/arch/arm/mach-shmobile/include/mach/rcar-gen2.h b/arch/arm/mach-shmobile/include/mach/rcar-gen2.h new file mode 100644 index 000000000000..43f606eb2d82 --- /dev/null +++ b/arch/arm/mach-shmobile/include/mach/rcar-gen2.h @@ -0,0 +1,8 @@ +#ifndef __ASM_RCAR_GEN2_H__ +#define __ASM_RCAR_GEN2_H__ + +void rcar_gen2_timer_init(void); +#define MD(nr) BIT(nr) +u32 rcar_gen2_read_mode_pins(void); + +#endif /* __ASM_RCAR_GEN2_H__ */ diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c index c7e24eff9ba2..c47bcebbcb00 100644 --- a/arch/arm/mach-shmobile/setup-r8a7790.c +++ b/arch/arm/mach-shmobile/setup-r8a7790.c @@ -18,7 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include #include #include #include @@ -203,71 +202,6 @@ void __init r8a7790_add_standard_devices(void) r8a7790_register_thermal(); } -#define MODEMR 0xe6160060 - -u32 __init r8a7790_read_mode_pins(void) -{ - void __iomem *modemr = ioremap_nocache(MODEMR, 4); - u32 mode; - - BUG_ON(!modemr); - mode = ioread32(modemr); - iounmap(modemr); - - return mode; -} - -#define CNTCR 0 -#define CNTFID0 0x20 - -void __init r8a7790_timer_init(void) -{ -#ifdef CONFIG_ARM_ARCH_TIMER - u32 mode = r8a7790_read_mode_pins(); - void __iomem *base; - int extal_mhz = 0; - u32 freq; - - /* At Linux boot time the r8a7790 arch timer comes up - * with the counter disabled. Moreover, it may also report - * a potentially incorrect fixed 13 MHz frequency. To be - * correct these registers need to be updated to use the - * frequency EXTAL / 2 which can be determined by the MD pins. - */ - - switch (mode & (MD(14) | MD(13))) { - case 0: - extal_mhz = 15; - break; - case MD(13): - extal_mhz = 20; - break; - case MD(14): - extal_mhz = 26; - break; - case MD(13) | MD(14): - extal_mhz = 30; - break; - } - - /* The arch timer frequency equals EXTAL / 2 */ - freq = extal_mhz * (1000000 / 2); - - /* Remap "armgcnt address map" space */ - base = ioremap(0xe6080000, PAGE_SIZE); - - /* Update registers with correct frequency */ - iowrite32(freq, base + CNTFID0); - asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r" (freq)); - - /* make sure arch timer is started by setting bit 0 of CNTCR */ - iowrite32(1, base + CNTCR); - iounmap(base); -#endif /* CONFIG_ARM_ARCH_TIMER */ - - clocksource_of_init(); -} - void __init r8a7790_init_early(void) { #ifndef CONFIG_ARM_ARCH_TIMER @@ -285,7 +219,7 @@ static const char * const r8a7790_boards_compat_dt[] __initconst = { DT_MACHINE_START(R8A7790_DT, "Generic R8A7790 (Flattened Device Tree)") .smp = smp_ops(r8a7790_smp_ops), .init_early = r8a7790_init_early, - .init_time = r8a7790_timer_init, + .init_time = rcar_gen2_timer_init, .dt_compat = r8a7790_boards_compat_dt, MACHINE_END #endif /* CONFIG_USE_OF */ diff --git a/arch/arm/mach-shmobile/setup-rcar-gen2.c b/arch/arm/mach-shmobile/setup-rcar-gen2.c new file mode 100644 index 000000000000..5734c24bf6c7 --- /dev/null +++ b/arch/arm/mach-shmobile/setup-rcar-gen2.c @@ -0,0 +1,91 @@ +/* + * R-Car Generation 2 support + * + * Copyright (C) 2013 Renesas Solutions Corp. + * Copyright (C) 2013 Magnus Damm + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include + +#define MODEMR 0xe6160060 + +u32 __init rcar_gen2_read_mode_pins(void) +{ + void __iomem *modemr = ioremap_nocache(MODEMR, 4); + u32 mode; + + BUG_ON(!modemr); + mode = ioread32(modemr); + iounmap(modemr); + + return mode; +} + +#define CNTCR 0 +#define CNTFID0 0x20 + +void __init rcar_gen2_timer_init(void) +{ +#ifdef CONFIG_ARM_ARCH_TIMER + u32 mode = rcar_gen2_read_mode_pins(); + void __iomem *base; + int extal_mhz = 0; + u32 freq; + + /* At Linux boot time the r8a7790 arch timer comes up + * with the counter disabled. Moreover, it may also report + * a potentially incorrect fixed 13 MHz frequency. To be + * correct these registers need to be updated to use the + * frequency EXTAL / 2 which can be determined by the MD pins. + */ + + switch (mode & (MD(14) | MD(13))) { + case 0: + extal_mhz = 15; + break; + case MD(13): + extal_mhz = 20; + break; + case MD(14): + extal_mhz = 26; + break; + case MD(13) | MD(14): + extal_mhz = 30; + break; + } + + /* The arch timer frequency equals EXTAL / 2 */ + freq = extal_mhz * (1000000 / 2); + + /* Remap "armgcnt address map" space */ + base = ioremap(0xe6080000, PAGE_SIZE); + + /* Update registers with correct frequency */ + iowrite32(freq, base + CNTFID0); + asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r" (freq)); + + /* make sure arch timer is started by setting bit 0 of CNTCR */ + iowrite32(1, base + CNTCR); + iounmap(base); +#endif /* CONFIG_ARM_ARCH_TIMER */ + + clocksource_of_init(); +} -- cgit v1.2.3 From 4275881fcacae2b1662d64e7989959ef3c33cf52 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 1 Oct 2013 17:11:53 +0900 Subject: ARM: shmobile: Introduce r8a7791_add_standard_devices() Introduce the function r8a7791_add_standard_devices() that follows the same style as other mach-shmobile SoC code and allows C version of board code to add on-chip devices. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/include/mach/r8a7791.h | 1 + arch/arm/mach-shmobile/setup-r8a7791.c | 5 +++++ 2 files changed, 6 insertions(+) (limited to 'arch/arm/mach-shmobile/include') diff --git a/arch/arm/mach-shmobile/include/mach/r8a7791.h b/arch/arm/mach-shmobile/include/mach/r8a7791.h index 2e6d66131083..2a86a5394672 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7791.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7791.h @@ -1,6 +1,7 @@ #ifndef __ASM_R8A7791_H__ #define __ASM_R8A7791_H__ +void r8a7791_add_standard_devices(void); void r8a7791_add_dt_devices(void); void r8a7791_clock_init(void); void r8a7791_init_early(void); diff --git a/arch/arm/mach-shmobile/setup-r8a7791.c b/arch/arm/mach-shmobile/setup-r8a7791.c index b56399d2e1de..350dfc4918e3 100644 --- a/arch/arm/mach-shmobile/setup-r8a7791.c +++ b/arch/arm/mach-shmobile/setup-r8a7791.c @@ -129,6 +129,11 @@ void __init r8a7791_add_dt_devices(void) r8a7791_register_cmt(00); } +void __init r8a7791_add_standard_devices(void) +{ + r8a7791_add_dt_devices(); +} + void __init r8a7791_init_early(void) { #ifndef CONFIG_ARM_ARCH_TIMER -- cgit v1.2.3 From e3da5b36d48a8e55d1549da016e4c38ff3c0d0fc Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 19 Sep 2013 05:11:11 +0900 Subject: ARM: shmobile: Initial r7s72100 SoC support Add initial support for the r7272100 SoC including: - Single Cortex-A9 CPU Core - GIC No static virtual mappings are used, all the components make use of ioremap(). DT_MACHINE_START is still wrapped in CONFIG_USE_OF to match other mach-shmobile code. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/boot/dts/r7s72100.dtsi | 36 +++++ arch/arm/mach-shmobile/Kconfig | 6 + arch/arm/mach-shmobile/Makefile | 2 + arch/arm/mach-shmobile/clock-r7s72100.c | 194 +++++++++++++++++++++++++ arch/arm/mach-shmobile/include/mach/r7s72100.h | 7 + arch/arm/mach-shmobile/setup-r7s72100.c | 43 ++++++ 6 files changed, 288 insertions(+) create mode 100644 arch/arm/boot/dts/r7s72100.dtsi create mode 100644 arch/arm/mach-shmobile/clock-r7s72100.c create mode 100644 arch/arm/mach-shmobile/include/mach/r7s72100.h create mode 100644 arch/arm/mach-shmobile/setup-r7s72100.c (limited to 'arch/arm/mach-shmobile/include') diff --git a/arch/arm/boot/dts/r7s72100.dtsi b/arch/arm/boot/dts/r7s72100.dtsi new file mode 100644 index 000000000000..46b82aa7dc4e --- /dev/null +++ b/arch/arm/boot/dts/r7s72100.dtsi @@ -0,0 +1,36 @@ +/* + * Device Tree Source for the r7s72100 SoC + * + * Copyright (C) 2013 Renesas Solutions Corp. + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +/ { + compatible = "renesas,r7s72100"; + interrupt-parent = <&gic>; + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + reg = <0>; + }; + }; + + gic: interrupt-controller@e8201000 { + compatible = "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + reg = <0xe8201000 0x1000>, + <0xe8202000 0x1000>; + }; +}; diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index b45240512ce0..5dd5f9f7897a 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig @@ -113,6 +113,12 @@ config ARCH_EMEV2 select ARM_GIC select CPU_V7 +config ARCH_R7S72100 + bool "RZ/A1H (R7S72100)" + select ARM_GIC + select CPU_V7 + select SH_CLK_CPG + comment "SH-Mobile Board Type" config MACH_APE6EVM diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index 3c37e8271dfe..95e48d129ddc 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_ARCH_R8A7790) += setup-r8a7790.o obj-$(CONFIG_ARCH_R8A7790) += setup-r8a7790.o setup-rcar-gen2.o obj-$(CONFIG_ARCH_R8A7791) += setup-r8a7791.o setup-rcar-gen2.o obj-$(CONFIG_ARCH_EMEV2) += setup-emev2.o +obj-$(CONFIG_ARCH_R7S72100) += setup-r7s72100.o # Clock objects ifndef CONFIG_COMMON_CLK @@ -31,6 +32,7 @@ obj-$(CONFIG_ARCH_R8A7779) += clock-r8a7779.o obj-$(CONFIG_ARCH_R8A7790) += clock-r8a7790.o obj-$(CONFIG_ARCH_R8A7791) += clock-r8a7791.o obj-$(CONFIG_ARCH_EMEV2) += clock-emev2.o +obj-$(CONFIG_ARCH_R7S72100) += clock-r7s72100.o endif # SMP objects diff --git a/arch/arm/mach-shmobile/clock-r7s72100.c b/arch/arm/mach-shmobile/clock-r7s72100.c new file mode 100644 index 000000000000..1e71094f809d --- /dev/null +++ b/arch/arm/mach-shmobile/clock-r7s72100.c @@ -0,0 +1,194 @@ +/* + * r7a72100 clock framework support + * + * Copyright (C) 2013 Renesas Solutions Corp. + * Copyright (C) 2012 Phil Edworthy + * Copyright (C) 2011 Magnus Damm + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include + +/* registers */ +#define FRQCR 0xfcfe0010 +#define FRQCR2 0xfcfe0014 +#define STBCR3 0xfcfe0420 +#define STBCR4 0xfcfe0424 + +#define PLL_RATE 30 + +static struct clk_mapping cpg_mapping = { + .phys = 0xfcfe0000, + .len = 0x1000, +}; + +/* Fixed 32 KHz root clock for RTC */ +static struct clk r_clk = { + .rate = 32768, +}; + +/* + * Default rate for the root input clock, reset this with clk_set_rate() + * from the platform code. + */ +static struct clk extal_clk = { + .rate = 13330000, + .mapping = &cpg_mapping, +}; + +static unsigned long pll_recalc(struct clk *clk) +{ + return clk->parent->rate * PLL_RATE; +} + +static struct sh_clk_ops pll_clk_ops = { + .recalc = pll_recalc, +}; + +static struct clk pll_clk = { + .ops = &pll_clk_ops, + .parent = &extal_clk, + .flags = CLK_ENABLE_ON_INIT, +}; + +static unsigned long bus_recalc(struct clk *clk) +{ + return clk->parent->rate * 2 / 3; +} + +static struct sh_clk_ops bus_clk_ops = { + .recalc = bus_recalc, +}; + +static struct clk bus_clk = { + .ops = &bus_clk_ops, + .parent = &pll_clk, + .flags = CLK_ENABLE_ON_INIT, +}; + +static unsigned long peripheral0_recalc(struct clk *clk) +{ + return clk->parent->rate / 12; +} + +static struct sh_clk_ops peripheral0_clk_ops = { + .recalc = peripheral0_recalc, +}; + +static struct clk peripheral0_clk = { + .ops = &peripheral0_clk_ops, + .parent = &pll_clk, + .flags = CLK_ENABLE_ON_INIT, +}; + +static unsigned long peripheral1_recalc(struct clk *clk) +{ + return clk->parent->rate / 6; +} + +static struct sh_clk_ops peripheral1_clk_ops = { + .recalc = peripheral1_recalc, +}; + +static struct clk peripheral1_clk = { + .ops = &peripheral1_clk_ops, + .parent = &pll_clk, + .flags = CLK_ENABLE_ON_INIT, +}; + +struct clk *main_clks[] = { + &r_clk, + &extal_clk, + &pll_clk, + &bus_clk, + &peripheral0_clk, + &peripheral1_clk, +}; + +static int div2[] = { 1, 3, 0, 3 }; /* 1, 2/3, reserve, 1/3 */ +static int multipliers[] = { 1, 2, 1, 1 }; + +static struct clk_div_mult_table div4_div_mult_table = { + .divisors = div2, + .nr_divisors = ARRAY_SIZE(div2), + .multipliers = multipliers, + .nr_multipliers = ARRAY_SIZE(multipliers), +}; + +static struct clk_div4_table div4_table = { + .div_mult_table = &div4_div_mult_table, +}; + +enum { DIV4_I, + DIV4_NR }; + +#define DIV4(_reg, _bit, _mask, _flags) \ + SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags) + +/* The mask field specifies the div2 entries that are valid */ +struct clk div4_clks[DIV4_NR] = { + [DIV4_I] = DIV4(FRQCR, 8, 0xB, CLK_ENABLE_REG_16BIT + | CLK_ENABLE_ON_INIT), +}; + +enum { MSTP47, MSTP46, MSTP45, MSTP44, MSTP43, MSTP42, MSTP41, MSTP40, + MSTP33, MSTP_NR }; + +static struct clk mstp_clks[MSTP_NR] = { + [MSTP47] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 7, 0), /* SCIF0 */ + [MSTP46] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 6, 0), /* SCIF1 */ + [MSTP45] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 5, 0), /* SCIF2 */ + [MSTP44] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 4, 0), /* SCIF3 */ + [MSTP43] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 3, 0), /* SCIF4 */ + [MSTP42] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 2, 0), /* SCIF5 */ + [MSTP41] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 1, 0), /* SCIF6 */ + [MSTP40] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 0, 0), /* SCIF7 */ + [MSTP33] = SH_CLK_MSTP8(&peripheral0_clk, STBCR3, 3, 0), /* MTU2 */ +}; + +static struct clk_lookup lookups[] = { + /* main clocks */ + CLKDEV_CON_ID("rclk", &r_clk), + CLKDEV_CON_ID("extal", &extal_clk), + CLKDEV_CON_ID("pll_clk", &pll_clk), + CLKDEV_CON_ID("peripheral_clk", &peripheral1_clk), + + /* DIV4 clocks */ + CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]), + + /* MSTP clocks */ +}; + +void __init r7s72100_clock_init(void) +{ + int k, ret = 0; + + for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) + ret = clk_register(main_clks[k]); + + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); + + if (!ret) + ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); + + if (!ret) + ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); + + if (!ret) + shmobile_clk_init(); + else + panic("failed to setup rza1 clocks\n"); +} diff --git a/arch/arm/mach-shmobile/include/mach/r7s72100.h b/arch/arm/mach-shmobile/include/mach/r7s72100.h new file mode 100644 index 000000000000..f78062e98bd4 --- /dev/null +++ b/arch/arm/mach-shmobile/include/mach/r7s72100.h @@ -0,0 +1,7 @@ +#ifndef __ASM_R7S72100_H__ +#define __ASM_R7S72100_H__ + +void r7s72100_clock_init(void); +void r7s72100_init_early(void); + +#endif /* __ASM_R7S72100_H__ */ diff --git a/arch/arm/mach-shmobile/setup-r7s72100.c b/arch/arm/mach-shmobile/setup-r7s72100.c new file mode 100644 index 000000000000..c1aded0984a8 --- /dev/null +++ b/arch/arm/mach-shmobile/setup-r7s72100.c @@ -0,0 +1,43 @@ +/* + * r7s72100 processor support + * + * Copyright (C) 2013 Renesas Solutions Corp. + * Copyright (C) 2013 Magnus Damm + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include + +void __init r7s72100_init_early(void) +{ + shmobile_setup_delay(400, 1, 3); /* Cortex-A9 @ 400MHz */ +} + +#ifdef CONFIG_USE_OF +static const char *r7s72100_boards_compat_dt[] __initdata = { + "renesas,r7s72100", + NULL, +}; + +DT_MACHINE_START(R7S72100_DT, "Generic R7S72100 (Flattened Device Tree)") + .init_early = r7s72100_init_early, + .dt_compat = r7s72100_boards_compat_dt, +MACHINE_END +#endif /* CONFIG_USE_OF */ -- cgit v1.2.3 From f6ca6f11c921b227e33c5e91084be5ef30c32771 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 19 Sep 2013 05:11:20 +0900 Subject: ARM: shmobile: r7s72100 SCIF support Add SCIF serial port support to the r7s72100 SoC by adding platform devices for SCIF0 -> SCIF7 together with clock bindings. DT device description is excluded at this point since such bindings are still under development. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/clock-r7s72100.c | 8 +++++ arch/arm/mach-shmobile/include/mach/r7s72100.h | 1 + arch/arm/mach-shmobile/setup-r7s72100.c | 45 ++++++++++++++++++++++++++ 3 files changed, 54 insertions(+) (limited to 'arch/arm/mach-shmobile/include') diff --git a/arch/arm/mach-shmobile/clock-r7s72100.c b/arch/arm/mach-shmobile/clock-r7s72100.c index 1e71094f809d..4aba20ca127e 100644 --- a/arch/arm/mach-shmobile/clock-r7s72100.c +++ b/arch/arm/mach-shmobile/clock-r7s72100.c @@ -170,6 +170,14 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]), /* MSTP clocks */ + CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP47]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP46]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP45]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[MSTP44]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.4", &mstp_clks[MSTP43]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.5", &mstp_clks[MSTP42]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.6", &mstp_clks[MSTP41]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.7", &mstp_clks[MSTP40]), }; void __init r7s72100_clock_init(void) diff --git a/arch/arm/mach-shmobile/include/mach/r7s72100.h b/arch/arm/mach-shmobile/include/mach/r7s72100.h index f78062e98bd4..5f34b20ecd4a 100644 --- a/arch/arm/mach-shmobile/include/mach/r7s72100.h +++ b/arch/arm/mach-shmobile/include/mach/r7s72100.h @@ -1,6 +1,7 @@ #ifndef __ASM_R7S72100_H__ #define __ASM_R7S72100_H__ +void r7s72100_add_dt_devices(void); void r7s72100_clock_init(void); void r7s72100_init_early(void); diff --git a/arch/arm/mach-shmobile/setup-r7s72100.c b/arch/arm/mach-shmobile/setup-r7s72100.c index c1aded0984a8..d4eb509a1c87 100644 --- a/arch/arm/mach-shmobile/setup-r7s72100.c +++ b/arch/arm/mach-shmobile/setup-r7s72100.c @@ -21,10 +21,55 @@ #include #include #include +#include #include +#include #include #include +#define SCIF_DATA(index, baseaddr, irq) \ +[index] = { \ + .type = PORT_SCIF, \ + .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, \ + .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, \ + .scbrr_algo_id = SCBRR_ALGO_2, \ + .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE | \ + SCSCR_REIE, \ + .mapbase = baseaddr, \ + .irqs = { irq + 1, irq + 2, irq + 3, irq }, \ +} + +enum { SCIF0, SCIF1, SCIF2, SCIF3, SCIF4, SCIF5, SCIF6, SCIF7 }; + +static const struct plat_sci_port scif[] __initconst = { + SCIF_DATA(SCIF0, 0xe8007000, gic_iid(221)), /* SCIF0 */ + SCIF_DATA(SCIF1, 0xe8007800, gic_iid(225)), /* SCIF1 */ + SCIF_DATA(SCIF2, 0xe8008000, gic_iid(229)), /* SCIF2 */ + SCIF_DATA(SCIF3, 0xe8008800, gic_iid(233)), /* SCIF3 */ + SCIF_DATA(SCIF4, 0xe8009000, gic_iid(237)), /* SCIF4 */ + SCIF_DATA(SCIF5, 0xe8009800, gic_iid(241)), /* SCIF5 */ + SCIF_DATA(SCIF6, 0xe800a000, gic_iid(245)), /* SCIF6 */ + SCIF_DATA(SCIF7, 0xe800a800, gic_iid(249)), /* SCIF7 */ +}; + +static inline void r7s72100_register_scif(int idx) +{ + platform_device_register_data(&platform_bus, "sh-sci", idx, &scif[idx], + sizeof(struct plat_sci_port)); +} + +void __init r7s72100_add_dt_devices(void) +{ + r7s72100_register_scif(SCIF0); + r7s72100_register_scif(SCIF1); + r7s72100_register_scif(SCIF2); + r7s72100_register_scif(SCIF3); + r7s72100_register_scif(SCIF4); + r7s72100_register_scif(SCIF5); + r7s72100_register_scif(SCIF6); + r7s72100_register_scif(SCIF7); +} + void __init r7s72100_init_early(void) { shmobile_setup_delay(400, 1, 3); /* Cortex-A9 @ 400MHz */ -- cgit v1.2.3 From 2238577b2c91587daf5f87ce414ef5b3703f81af Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 2 Oct 2013 01:31:40 -0700 Subject: ARM: shmobile: r8a7778: split r8a7778_init_irq_extpin() for DT r8a7778 INTC needs IRL pin mode settings to determine behavior of IRQ0 - IRQ3, and r8a7778_init_irq_extpin() is controlling it via irlm parameter. But this function registers renesas_intc_irqpin driver if irlm was set, and this value depends on platform. This is not good for DT. This patch splits r8a7778_init_irq_extpin() function into "mode settings" and "funtion register" parts. Signed-off-by: Kuninori Morimoto Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/include/mach/r8a7778.h | 1 + arch/arm/mach-shmobile/setup-r8a7778.c | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-shmobile/include') diff --git a/arch/arm/mach-shmobile/include/mach/r8a7778.h b/arch/arm/mach-shmobile/include/mach/r8a7778.h index 1d6fe973e8b4..dbe221a484d5 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7778.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7778.h @@ -41,6 +41,7 @@ extern void r8a7778_init_delay(void); extern void r8a7778_init_irq_dt(void); extern void r8a7778_clock_init(void); extern void r8a7778_init_irq_extpin(int irlm); +extern void r8a7778_init_irq_extpin_dt(int irlm); extern void r8a7778_pinmux_init(void); extern int r8a7778_usb_phy_power(bool enable); diff --git a/arch/arm/mach-shmobile/setup-r8a7778.c b/arch/arm/mach-shmobile/setup-r8a7778.c index fa1b7e44a973..16d49aa8b5db 100644 --- a/arch/arm/mach-shmobile/setup-r8a7778.c +++ b/arch/arm/mach-shmobile/setup-r8a7778.c @@ -476,7 +476,7 @@ static struct resource irqpin_resources[] __initdata = { DEFINE_RES_IRQ(gic_iid(0x3e)), /* IRQ3 */ }; -void __init r8a7778_init_irq_extpin(int irlm) +void __init r8a7778_init_irq_extpin_dt(int irlm) { void __iomem *icr0 = ioremap_nocache(0xfe780000, PAGE_SIZE); unsigned long tmp; @@ -494,7 +494,11 @@ void __init r8a7778_init_irq_extpin(int irlm) tmp |= (1 << 21); /* LVLMODE = 1 */ iowrite32(tmp, icr0); iounmap(icr0); +} +void __init r8a7778_init_irq_extpin(int irlm) +{ + r8a7778_init_irq_extpin_dt(irlm); if (irlm) platform_device_register_resndata( &platform_bus, "renesas_intc_irqpin", -1, -- cgit v1.2.3 From 31e4e292f85189f01949124b04aabb3b50ba3e86 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 2 Oct 2013 01:38:23 -0700 Subject: ARM: shmobile: r8a7779: split r8a7779_init_irq_extpin() for DT r8a7779 INTC needs IRL pin mode settings to determine behavior of IRQ0 - IRQ3, and r8a7779_init_irq_extpin() is controlling it via irlm parameter. But this function registers renesas_intc_irqpin driver if irlm was set, and this value depends on platform. This is not good for DT. This patch splits r8a7779_init_irq_extpin() function into "mode settings" and "funtion register" parts Signed-off-by: Kuninori Morimoto Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/include/mach/r8a7779.h | 1 + arch/arm/mach-shmobile/setup-r8a7779.c | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-shmobile/include') diff --git a/arch/arm/mach-shmobile/include/mach/r8a7779.h b/arch/arm/mach-shmobile/include/mach/r8a7779.h index 31e87b92a9c3..17af34ed89c8 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7779.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7779.h @@ -33,6 +33,7 @@ static inline struct r8a7779_pm_ch *to_r8a7779_ch(struct generic_pm_domain *d) extern void r8a7779_init_delay(void); extern void r8a7779_init_irq_extpin(int irlm); +extern void r8a7779_init_irq_extpin_dt(int irlm); extern void r8a7779_init_irq_dt(void); extern void r8a7779_map_io(void); extern void r8a7779_earlytimer_init(void); diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c index eacb2f783693..13049e9d691c 100644 --- a/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/arch/arm/mach-shmobile/setup-r8a7779.c @@ -98,7 +98,7 @@ static struct resource irqpin0_resources[] __initdata = { DEFINE_RES_IRQ(gic_spi(30)), /* IRQ3 */ }; -void __init r8a7779_init_irq_extpin(int irlm) +void __init r8a7779_init_irq_extpin_dt(int irlm) { void __iomem *icr0 = ioremap_nocache(0xfe780000, PAGE_SIZE); u32 tmp; @@ -116,7 +116,11 @@ void __init r8a7779_init_irq_extpin(int irlm) tmp |= (1 << 21); /* LVLMODE = 1 */ iowrite32(tmp, icr0); iounmap(icr0); +} +void __init r8a7779_init_irq_extpin(int irlm) +{ + r8a7779_init_irq_extpin_dt(irlm); if (irlm) platform_device_register_resndata( &platform_bus, "renesas_intc_irqpin", -1, -- cgit v1.2.3 From 687c27b07050c21a62c4c975777c89e698649a6b Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 1 Oct 2013 17:13:16 +0900 Subject: ARM: shmobile: r8a7791 SMP support Tie in the APMU SMP code on r8a7791. When used together with the secondary CPU device node and smp_ops in the board specific code then this will allow use of the two Cortex-A15 cores in the r8a7791 SoC. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/Makefile | 1 + arch/arm/mach-shmobile/include/mach/r8a7791.h | 1 + arch/arm/mach-shmobile/setup-r8a7791.c | 1 + arch/arm/mach-shmobile/smp-r8a7791.c | 62 +++++++++++++++++++++++++++ 4 files changed, 65 insertions(+) create mode 100644 arch/arm/mach-shmobile/smp-r8a7791.c (limited to 'arch/arm/mach-shmobile/include') diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index 95e48d129ddc..f2d40edadcc9 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile @@ -40,6 +40,7 @@ smp-y := platsmp.o headsmp.o smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o headsmp-scu.o platsmp-scu.o smp-$(CONFIG_ARCH_R8A7779) += smp-r8a7779.o headsmp-scu.o platsmp-scu.o smp-$(CONFIG_ARCH_R8A7790) += smp-r8a7790.o platsmp-apmu.o +smp-$(CONFIG_ARCH_R8A7791) += smp-r8a7791.o platsmp-apmu.o smp-$(CONFIG_ARCH_EMEV2) += smp-emev2.o headsmp-scu.o platsmp-scu.o # IRQ objects diff --git a/arch/arm/mach-shmobile/include/mach/r8a7791.h b/arch/arm/mach-shmobile/include/mach/r8a7791.h index 2a86a5394672..051ead3c286e 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7791.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7791.h @@ -5,5 +5,6 @@ void r8a7791_add_standard_devices(void); void r8a7791_add_dt_devices(void); void r8a7791_clock_init(void); void r8a7791_init_early(void); +extern struct smp_operations r8a7791_smp_ops; #endif /* __ASM_R8A7791_H__ */ diff --git a/arch/arm/mach-shmobile/setup-r8a7791.c b/arch/arm/mach-shmobile/setup-r8a7791.c index cb3859b4cc95..d9393d61ee27 100644 --- a/arch/arm/mach-shmobile/setup-r8a7791.c +++ b/arch/arm/mach-shmobile/setup-r8a7791.c @@ -176,6 +176,7 @@ static const char *r8a7791_boards_compat_dt[] __initdata = { }; DT_MACHINE_START(R8A7791_DT, "Generic R8A7791 (Flattened Device Tree)") + .smp = smp_ops(r8a7791_smp_ops), .init_early = r8a7791_init_early, .init_time = rcar_gen2_timer_init, .dt_compat = r8a7791_boards_compat_dt, diff --git a/arch/arm/mach-shmobile/smp-r8a7791.c b/arch/arm/mach-shmobile/smp-r8a7791.c new file mode 100644 index 000000000000..2df5bd190fe4 --- /dev/null +++ b/arch/arm/mach-shmobile/smp-r8a7791.c @@ -0,0 +1,62 @@ +/* + * SMP support for r8a7791 + * + * Copyright (C) 2013 Renesas Solutions Corp. + * Copyright (C) 2013 Magnus Damm + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include + +#define RST 0xe6160000 +#define CA15BAR 0x0020 +#define CA15RESCNT 0x0040 +#define RAM 0xe6300000 + +static void __init r8a7791_smp_prepare_cpus(unsigned int max_cpus) +{ + void __iomem *p; + u32 bar; + + /* let APMU code install data related to shmobile_boot_vector */ + shmobile_smp_apmu_prepare_cpus(max_cpus); + + /* RAM for jump stub, because BAR requires 256KB aligned address */ + p = ioremap_nocache(RAM, shmobile_boot_size); + memcpy_toio(p, shmobile_boot_vector, shmobile_boot_size); + iounmap(p); + + /* setup reset vectors */ + p = ioremap_nocache(RST, 0x63); + bar = (RAM >> 8) & 0xfffffc00; + writel_relaxed(bar, p + CA15BAR); + writel_relaxed(bar | 0x10, p + CA15BAR); + + /* enable clocks to all CPUs */ + writel_relaxed((readl_relaxed(p + CA15RESCNT) & ~0x0f) | 0xa5a50000, + p + CA15RESCNT); + iounmap(p); +} + +struct smp_operations r8a7791_smp_ops __initdata = { + .smp_prepare_cpus = r8a7791_smp_prepare_cpus, + .smp_boot_secondary = shmobile_smp_apmu_boot_secondary, +#ifdef CONFIG_HOTPLUG_CPU + .cpu_disable = shmobile_smp_cpu_disable, + .cpu_die = shmobile_smp_apmu_cpu_die, + .cpu_kill = shmobile_smp_apmu_cpu_kill, +#endif +}; -- cgit v1.2.3