diff options
Diffstat (limited to 'arch/arm/mach-shmobile')
30 files changed, 458 insertions, 165 deletions
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index 3a6e3c20a86d..e15dff790dbb 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig @@ -12,6 +12,7 @@ menuconfig ARCH_SHMOBILE_MULTI select NO_IOPORT_MAP select PINCTRL select ARCH_REQUIRE_GPIOLIB + select ARCH_HAS_OPP if ARCH_SHMOBILE_MULTI @@ -25,6 +26,11 @@ config ARCH_R7S72100 bool "RZ/A1H (R7S72100)" select SYS_SUPPORTS_SH_MTU2 +config ARCH_R8A7779 + bool "R-Car H1 (R8A77790)" + select RENESAS_INTC_IRQPIN + select SYS_SUPPORTS_SH_TMU + config ARCH_R8A7790 bool "R-Car H2 (R8A77900)" select RENESAS_IRQC @@ -51,6 +57,11 @@ config MACH_LAGER depends on ARCH_R8A7790 select MICREL_PHY if SH_ETH +config MACH_MARZEN + bool "MARZEN board" + depends on ARCH_R8A7779 + select REGULATOR_FIXED_VOLTAGE if REGULATOR + comment "Renesas ARM SoCs System Configuration" endif @@ -233,19 +244,6 @@ config MACH_MARZEN select REGULATOR_FIXED_VOLTAGE if REGULATOR select USE_OF -config MACH_MARZEN_REFERENCE - bool "MARZEN board - Reference Device Tree Implementation" - depends on ARCH_R8A7779 - select ARCH_REQUIRE_GPIOLIB - select REGULATOR_FIXED_VOLTAGE if REGULATOR - select USE_OF - ---help--- - Use reference implementation of Marzen board support - which makes use of device tree at the expense - of not supporting a number of devices. - - This is intended to aid developers - config MACH_LAGER bool "Lager board" depends on ARCH_R8A7790 diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index 38d5fe825e93..fe3878a1a69a 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile @@ -34,31 +34,39 @@ obj-$(CONFIG_ARCH_R8A7791) += clock-r8a7791.o obj-$(CONFIG_ARCH_R7S72100) += clock-r7s72100.o endif +# CPU reset vector handling objects +cpu-y := platsmp.o headsmp.o +cpu-$(CONFIG_ARCH_R8A7790) += platsmp-apmu.o +cpu-$(CONFIG_ARCH_R8A7791) += platsmp-apmu.o + # SMP objects -smp-y := platsmp.o headsmp.o +smp-y := $(cpu-y) 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_R8A7790) += smp-r8a7790.o +smp-$(CONFIG_ARCH_R8A7791) += smp-r8a7791.o smp-$(CONFIG_ARCH_EMEV2) += smp-emev2.o headsmp-scu.o platsmp-scu.o -# IRQ objects -obj-$(CONFIG_ARCH_SH7372) += entry-intc.o - # PM objects obj-$(CONFIG_SUSPEND) += suspend.o obj-$(CONFIG_CPU_IDLE) += cpuidle.o +obj-$(CONFIG_CPU_FREQ) += cpufreq.o obj-$(CONFIG_ARCH_SH7372) += pm-sh7372.o sleep-sh7372.o pm-rmobile.o obj-$(CONFIG_ARCH_SH73A0) += pm-sh73a0.o obj-$(CONFIG_ARCH_R8A7740) += pm-r8a7740.o pm-rmobile.o obj-$(CONFIG_ARCH_R8A7779) += pm-r8a7779.o pm-rcar.o -obj-$(CONFIG_ARCH_R8A7790) += pm-r8a7790.o pm-rcar.o +obj-$(CONFIG_ARCH_R8A7790) += pm-r8a7790.o pm-rcar.o $(cpu-y) +obj-$(CONFIG_ARCH_R8A7791) += pm-r8a7791.o pm-rcar.o $(cpu-y) + +# IRQ objects +obj-$(CONFIG_ARCH_SH7372) += entry-intc.o # Board objects ifdef CONFIG_ARCH_SHMOBILE_MULTI obj-$(CONFIG_MACH_GENMAI) += board-genmai-reference.o obj-$(CONFIG_MACH_KOELSCH) += board-koelsch-reference.o obj-$(CONFIG_MACH_LAGER) += board-lager-reference.o +obj-$(CONFIG_MACH_MARZEN) += board-marzen-reference.o else obj-$(CONFIG_MACH_APE6EVM) += board-ape6evm.o obj-$(CONFIG_MACH_APE6EVM_REFERENCE) += board-ape6evm-reference.o @@ -67,7 +75,6 @@ obj-$(CONFIG_MACH_BOCKW) += board-bockw.o obj-$(CONFIG_MACH_BOCKW_REFERENCE) += board-bockw-reference.o obj-$(CONFIG_MACH_GENMAI) += board-genmai.o obj-$(CONFIG_MACH_MARZEN) += board-marzen.o -obj-$(CONFIG_MACH_MARZEN_REFERENCE) += board-marzen-reference.o obj-$(CONFIG_MACH_LAGER) += board-lager.o obj-$(CONFIG_MACH_ARMADILLO800EVA) += board-armadillo800eva.o obj-$(CONFIG_MACH_ARMADILLO800EVA_REFERENCE) += board-armadillo800eva-reference.o diff --git a/arch/arm/mach-shmobile/Makefile.boot b/arch/arm/mach-shmobile/Makefile.boot index 918fccffa1b6..ebf97d4bcfd8 100644 --- a/arch/arm/mach-shmobile/Makefile.boot +++ b/arch/arm/mach-shmobile/Makefile.boot @@ -13,7 +13,6 @@ loadaddr-$(CONFIG_MACH_KZM9G_REFERENCE) += 0x41008000 loadaddr-$(CONFIG_MACH_LAGER) += 0x40008000 loadaddr-$(CONFIG_MACH_MACKEREL) += 0x40008000 loadaddr-$(CONFIG_MACH_MARZEN) += 0x60008000 -loadaddr-$(CONFIG_MACH_MARZEN_REFERENCE) += 0x60008000 __ZRELADDR := $(sort $(loadaddr-y)) zreladdr-y += $(__ZRELADDR) diff --git a/arch/arm/mach-shmobile/board-koelsch-reference.c b/arch/arm/mach-shmobile/board-koelsch-reference.c index 1d3f67d4ccd6..0b1fb2345aa1 100644 --- a/arch/arm/mach-shmobile/board-koelsch-reference.c +++ b/arch/arm/mach-shmobile/board-koelsch-reference.c @@ -23,11 +23,13 @@ #include <linux/kernel.h> #include <linux/of_platform.h> #include <linux/platform_data/rcar-du.h> -#include <mach/r8a7791.h> + #include <asm/mach/arch.h> + #include "clock.h" #include "common.h" #include "irqs.h" +#include "r8a7791.h" #include "rcar-gen2.h" /* DU */ diff --git a/arch/arm/mach-shmobile/board-koelsch.c b/arch/arm/mach-shmobile/board-koelsch.c index c932f2ca85b1..766442f82948 100644 --- a/arch/arm/mach-shmobile/board-koelsch.c +++ b/arch/arm/mach-shmobile/board-koelsch.c @@ -45,11 +45,13 @@ #include <linux/spi/flash.h> #include <linux/spi/rspi.h> #include <linux/spi/spi.h> -#include <mach/r8a7791.h> + #include <asm/mach-types.h> #include <asm/mach/arch.h> + #include "common.h" #include "irqs.h" +#include "r8a7791.h" #include "rcar-gen2.h" /* DU */ diff --git a/arch/arm/mach-shmobile/board-marzen-reference.c b/arch/arm/mach-shmobile/board-marzen-reference.c index 94bd57203ff5..21b3e1ca2261 100644 --- a/arch/arm/mach-shmobile/board-marzen-reference.c +++ b/arch/arm/mach-shmobile/board-marzen-reference.c @@ -19,19 +19,42 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include <mach/r8a7779.h> +#include <linux/clk/shmobile.h> +#include <linux/clocksource.h> +#include <linux/of_platform.h> + #include <asm/irq.h> #include <asm/mach/arch.h> + +#include "clock.h" #include "common.h" #include "irqs.h" +#include "r8a7779.h" + +static void __init marzen_init_timer(void) +{ + r8a7779_clocks_init(r8a7779_read_mode_pins()); + clocksource_of_init(); +} + +/* + * This is a really crude hack to provide clkdev support to platform + * devices until they get moved to DT. + */ +static const struct clk_name clk_names[] __initconst = { + { "tmu0", "fck", "sh-tmu.0" }, +}; static void __init marzen_init(void) { + shmobile_clk_workaround(clk_names, ARRAY_SIZE(clk_names), false); r8a7779_add_standard_devices_dt(); + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); r8a7779_init_irq_extpin_dt(1); /* IRQ1 as individual interrupt */ } static const char *marzen_boards_compat_dt[] __initdata = { + "renesas,marzen", "renesas,marzen-reference", NULL, }; @@ -39,7 +62,8 @@ static const char *marzen_boards_compat_dt[] __initdata = { DT_MACHINE_START(MARZEN, "marzen") .smp = smp_ops(r8a7779_smp_ops), .map_io = r8a7779_map_io, - .init_early = r8a7779_init_delay, + .init_early = shmobile_init_delay, + .init_time = marzen_init_timer, .nr_irqs = NR_IRQS_LEGACY, .init_irq = r8a7779_init_irq_dt, .init_machine = marzen_init, diff --git a/arch/arm/mach-shmobile/board-marzen.c b/arch/arm/mach-shmobile/board-marzen.c index d0b5b746fe05..e5cf4201e769 100644 --- a/arch/arm/mach-shmobile/board-marzen.c +++ b/arch/arm/mach-shmobile/board-marzen.c @@ -41,13 +41,15 @@ #include <linux/mmc/host.h> #include <linux/mmc/sh_mobile_sdhi.h> #include <linux/mfd/tmio.h> + #include <media/soc_camera.h> -#include <mach/r8a7779.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/traps.h> + #include "common.h" #include "irqs.h" +#include "r8a7779.h" /* Fixed 3.3V regulator to be used by SDHI0 */ static struct regulator_consumer_supply fixed3v3_power_consumers[] = { diff --git a/arch/arm/mach-shmobile/clock-r8a73a4.c b/arch/arm/mach-shmobile/clock-r8a73a4.c index 0f431498229b..49d139748aa6 100644 --- a/arch/arm/mach-shmobile/clock-r8a73a4.c +++ b/arch/arm/mach-shmobile/clock-r8a73a4.c @@ -574,11 +574,17 @@ static struct clk_lookup lookups[] = { /* MSTP */ CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), + CLKDEV_DEV_ID("e6c40000.serial", &mstp_clks[MSTP204]), CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), + CLKDEV_DEV_ID("e6c50000.serial", &mstp_clks[MSTP203]), CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP206]), + CLKDEV_DEV_ID("e6c20000.serial", &mstp_clks[MSTP206]), CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP207]), + CLKDEV_DEV_ID("e6c30000.serial", &mstp_clks[MSTP207]), CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP216]), + CLKDEV_DEV_ID("e6ce0000.serial", &mstp_clks[MSTP216]), CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP217]), + CLKDEV_DEV_ID("e6cf0000.serial", &mstp_clks[MSTP217]), CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), CLKDEV_DEV_ID("e6700020.dma-controller", &mstp_clks[MSTP218]), CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]), diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c index 789091cfa37a..a60c324df64e 100644 --- a/arch/arm/mach-shmobile/clock-r8a7740.c +++ b/arch/arm/mach-shmobile/clock-r8a7740.c @@ -556,27 +556,27 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[MSTP128]), CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), - CLKDEV_DEV_ID("e6c80000.sci", &mstp_clks[MSTP200]), + CLKDEV_DEV_ID("e6c80000.serial", &mstp_clks[MSTP200]), CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), - CLKDEV_DEV_ID("e6c70000.sci", &mstp_clks[MSTP201]), + CLKDEV_DEV_ID("e6c70000.serial", &mstp_clks[MSTP201]), CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), - CLKDEV_DEV_ID("e6c60000.sci", &mstp_clks[MSTP202]), + CLKDEV_DEV_ID("e6c60000.serial", &mstp_clks[MSTP202]), CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), - CLKDEV_DEV_ID("e6c50000.sci", &mstp_clks[MSTP203]), + CLKDEV_DEV_ID("e6c50000.serial", &mstp_clks[MSTP203]), CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), - CLKDEV_DEV_ID("e6c40000.sci", &mstp_clks[MSTP204]), + CLKDEV_DEV_ID("e6c40000.serial", &mstp_clks[MSTP204]), CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]), - CLKDEV_DEV_ID("e6c30000.sci", &mstp_clks[MSTP206]), + CLKDEV_DEV_ID("e6c30000.serial", &mstp_clks[MSTP206]), CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), - CLKDEV_DEV_ID("e6cb0000.sci", &mstp_clks[MSTP207]), + CLKDEV_DEV_ID("e6cb0000.serial", &mstp_clks[MSTP207]), CLKDEV_DEV_ID("sh-dma-engine.3", &mstp_clks[MSTP214]), CLKDEV_DEV_ID("sh-dma-engine.2", &mstp_clks[MSTP216]), CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]), CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP222]), - CLKDEV_DEV_ID("e6cd0000.sci", &mstp_clks[MSTP222]), + CLKDEV_DEV_ID("e6cd0000.serial", &mstp_clks[MSTP222]), CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP230]), - CLKDEV_DEV_ID("e6cc0000.sci", &mstp_clks[MSTP230]), + CLKDEV_DEV_ID("e6cc0000.serial", &mstp_clks[MSTP230]), CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), CLKDEV_DEV_ID("fe1f0000.sound", &mstp_clks[MSTP328]), diff --git a/arch/arm/mach-shmobile/clock-r8a7778.c b/arch/arm/mach-shmobile/clock-r8a7778.c index 16bbc94a1520..95579073cfce 100644 --- a/arch/arm/mach-shmobile/clock-r8a7778.c +++ b/arch/arm/mach-shmobile/clock-r8a7778.c @@ -202,11 +202,17 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("i2c-rcar.3", &mstp_clks[MSTP027]), /* I2C3 */ CLKDEV_DEV_ID("ffc73000.i2c", &mstp_clks[MSTP027]), /* I2C3 */ CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP026]), /* SCIF0 */ + CLKDEV_DEV_ID("ffe40000.serial", &mstp_clks[MSTP026]), /* SCIF0 */ CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP025]), /* SCIF1 */ + CLKDEV_DEV_ID("ffe41000.serial", &mstp_clks[MSTP025]), /* SCIF1 */ CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP024]), /* SCIF2 */ + CLKDEV_DEV_ID("ffe42000.serial", &mstp_clks[MSTP024]), /* SCIF2 */ CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP023]), /* SCIF3 */ + CLKDEV_DEV_ID("ffe43000.serial", &mstp_clks[MSTP023]), /* SCIF3 */ CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP022]), /* SCIF4 */ + CLKDEV_DEV_ID("ffe44000.serial", &mstp_clks[MSTP022]), /* SCIF4 */ CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP021]), /* SCIF6 */ + CLKDEV_DEV_ID("ffe45000.serial", &mstp_clks[MSTP021]), /* SCIF5 */ CLKDEV_DEV_ID("sh-hspi.0", &mstp_clks[MSTP007]), /* HSPI0 */ CLKDEV_DEV_ID("fffc7000.spi", &mstp_clks[MSTP007]), /* HSPI0 */ CLKDEV_DEV_ID("sh-hspi.1", &mstp_clks[MSTP007]), /* HSPI1 */ diff --git a/arch/arm/mach-shmobile/clock-r8a7779.c b/arch/arm/mach-shmobile/clock-r8a7779.c index d81539a26dbd..c51f9db3f66f 100644 --- a/arch/arm/mach-shmobile/clock-r8a7779.c +++ b/arch/arm/mach-shmobile/clock-r8a7779.c @@ -23,8 +23,11 @@ #include <linux/io.h> #include <linux/sh_clk.h> #include <linux/clkdev.h> +#include <linux/sh_timer.h> + #include "clock.h" #include "common.h" +#include "r8a7779.h" /* * MD1 = 1 MD1 = 0 @@ -52,9 +55,6 @@ #define MSTPCR3 IOMEM(0xffc8003c) #define MSTPSR1 IOMEM(0xffc80044) -#define MODEMR 0xffcc0020 - - /* ioremap() through clock mapping mandatory to avoid * collision with ARM coherent DMA virtual memory range. */ @@ -207,14 +207,9 @@ static struct clk_lookup lookups[] = { void __init r8a7779_clock_init(void) { - void __iomem *modemr = ioremap_nocache(MODEMR, PAGE_SIZE); - u32 mode; + u32 mode = r8a7779_read_mode_pins(); int k, ret = 0; - BUG_ON(!modemr); - mode = ioread32(modemr); - iounmap(modemr); - if (mode & MD(1)) { plla_clk.rate = 1500000000; @@ -268,3 +263,13 @@ void __init r8a7779_clock_init(void) else panic("failed to setup r8a7779 clocks\n"); } + +/* do nothing for !CONFIG_SMP or !CONFIG_HAVE_TWD */ +void __init __weak r8a7779_register_twd(void) { } + +void __init r8a7779_earlytimer_init(void) +{ + r8a7779_clock_init(); + r8a7779_register_twd(); + shmobile_earlytimer_init(); +} diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c index 37f48383e05a..9433a4e2c88e 100644 --- a/arch/arm/mach-shmobile/clock-sh73a0.c +++ b/arch/arm/mach-shmobile/clock-sh73a0.c @@ -638,16 +638,25 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("e6820000.i2c", &mstp_clks[MSTP116]), /* I2C0 */ CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */ CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP219]), /* SCIFA7 */ + CLKDEV_DEV_ID("e6cd0000.serial", &mstp_clks[MSTP219]), /* SCIFA7 */ CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* SY-DMAC */ CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]), /* MP-DMAC */ CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */ + CLKDEV_DEV_ID("e6cb0000.serial", &mstp_clks[MSTP207]), /* SCIFA5 */ CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]), /* SCIFB */ + CLKDEV_DEV_ID("0xe6c3000.serial", &mstp_clks[MSTP206]), /* SCIFB */ CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */ + CLKDEV_DEV_ID("e6c40000.serial", &mstp_clks[MSTP204]), /* SCIFA0 */ CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */ + CLKDEV_DEV_ID("e6c50000.serial", &mstp_clks[MSTP203]), /* SCIFA1 */ CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */ + CLKDEV_DEV_ID("e6c60000.serial", &mstp_clks[MSTP202]), /* SCIFA2 */ CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */ + CLKDEV_DEV_ID("e6c70000.serial", &mstp_clks[MSTP201]), /* SCIFA3 */ CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */ + CLKDEV_DEV_ID("e6c80000.serial", &mstp_clks[MSTP200]), /* SCIFA4 */ CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */ + CLKDEV_DEV_ID("e6cc0000.serial", &mstp_clks[MSTP331]), /* SCIFA6 */ CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI */ CLKDEV_DEV_ID("ec230000.sound", &mstp_clks[MSTP328]), /* FSI */ CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */ diff --git a/arch/arm/mach-shmobile/common.h b/arch/arm/mach-shmobile/common.h index f7a360edcc35..98056081f0da 100644 --- a/arch/arm/mach-shmobile/common.h +++ b/arch/arm/mach-shmobile/common.h @@ -35,8 +35,10 @@ extern void shmobile_cpuidle_set_driver(struct cpuidle_driver *drv); #ifdef CONFIG_SUSPEND int shmobile_suspend_init(void); +void shmobile_smp_apmu_suspend_init(void); #else static inline int shmobile_suspend_init(void) { return 0; } +static inline void shmobile_smp_apmu_suspend_init(void) { } #endif #ifdef CONFIG_CPU_IDLE @@ -45,12 +47,19 @@ int shmobile_cpuidle_init(void); static inline int shmobile_cpuidle_init(void) { return 0; } #endif +#ifdef CONFIG_CPU_FREQ +int shmobile_cpufreq_init(void); +#else +static inline int shmobile_cpufreq_init(void) { return 0; } +#endif + extern void __iomem *shmobile_scu_base; static inline void __init shmobile_init_late(void) { shmobile_suspend_init(); shmobile_cpuidle_init(); + shmobile_cpufreq_init(); } #endif /* __ARCH_MACH_COMMON_H */ diff --git a/arch/arm/mach-shmobile/cpufreq.c b/arch/arm/mach-shmobile/cpufreq.c new file mode 100644 index 000000000000..8a24b2be46ae --- /dev/null +++ b/arch/arm/mach-shmobile/cpufreq.c @@ -0,0 +1,17 @@ +/* + * CPUFreq support code for SH-Mobile ARM + * + * Copyright (C) 2014 Gaku Inami + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/platform_device.h> + +int __init shmobile_cpufreq_init(void) +{ + platform_device_register_simple("cpufreq-cpu0", -1, NULL, 0); + return 0; +} diff --git a/arch/arm/mach-shmobile/headsmp.S b/arch/arm/mach-shmobile/headsmp.S index 293007579b8e..50c491567e11 100644 --- a/arch/arm/mach-shmobile/headsmp.S +++ b/arch/arm/mach-shmobile/headsmp.S @@ -10,15 +10,18 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#include <linux/linkage.h> #include <linux/init.h> +#include <linux/linkage.h> +#include <linux/threads.h> #include <asm/assembler.h> #include <asm/memory.h> +#ifdef CONFIG_SMP ENTRY(shmobile_invalidate_start) bl v7_invalidate_l1 b secondary_startup ENDPROC(shmobile_invalidate_start) +#endif /* * Reset vector for secondary CPUs. @@ -69,7 +72,7 @@ shmobile_smp_boot_find_mpidr: shmobile_smp_boot_next: add r1, r1, #1 - cmp r1, #CONFIG_NR_CPUS + cmp r1, #NR_CPUS blo shmobile_smp_boot_find_mpidr b shmobile_smp_sleep @@ -86,10 +89,10 @@ ENDPROC(shmobile_smp_sleep) .globl shmobile_smp_mpidr shmobile_smp_mpidr: -1: .space CONFIG_NR_CPUS * 4 +1: .space NR_CPUS * 4 .globl shmobile_smp_fn shmobile_smp_fn: -2: .space CONFIG_NR_CPUS * 4 +2: .space NR_CPUS * 4 .globl shmobile_smp_arg shmobile_smp_arg: -3: .space CONFIG_NR_CPUS * 4 +3: .space NR_CPUS * 4 diff --git a/arch/arm/mach-shmobile/platsmp-apmu.c b/arch/arm/mach-shmobile/platsmp-apmu.c index fe648f5d8f06..2c06810d3a70 100644 --- a/arch/arm/mach-shmobile/platsmp-apmu.c +++ b/arch/arm/mach-shmobile/platsmp-apmu.c @@ -7,27 +7,32 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#include <linux/cpu_pm.h> #include <linux/delay.h> #include <linux/init.h> #include <linux/io.h> #include <linux/ioport.h> #include <linux/of_address.h> #include <linux/smp.h> +#include <linux/suspend.h> +#include <linux/threads.h> #include <asm/cacheflush.h> #include <asm/cp15.h> +#include <asm/proc-fns.h> #include <asm/smp_plat.h> +#include <asm/suspend.h> #include "common.h" static struct { void __iomem *iomem; int bit; -} apmu_cpus[CONFIG_NR_CPUS]; +} apmu_cpus[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) +static int __maybe_unused apmu_power_on(void __iomem *p, int bit) { /* request power on */ writel_relaxed(BIT(bit), p + WUPCR_OFFS); @@ -46,7 +51,7 @@ static int apmu_power_off(void __iomem *p, int bit) return 0; } -static int apmu_power_off_poll(void __iomem *p, int bit) +static int __maybe_unused apmu_power_off_poll(void __iomem *p, int bit) { int k; @@ -69,7 +74,7 @@ static int apmu_wrap(int cpu, int (*fn)(void __iomem *p, int cpu)) static void apmu_init_cpu(struct resource *res, int cpu, int bit) { - if (apmu_cpus[cpu].iomem) + if ((cpu >= ARRAY_SIZE(apmu_cpus)) || apmu_cpus[cpu].iomem) return; apmu_cpus[cpu].iomem = ioremap_nocache(res->start, resource_size(res)); @@ -133,6 +138,7 @@ void __init shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus) apmu_parse_cfg(apmu_init_cpu); } +#ifdef CONFIG_SMP int shmobile_smp_apmu_boot_secondary(unsigned int cpu, struct task_struct *idle) { /* For this particular CPU register boot vector */ @@ -140,8 +146,9 @@ int shmobile_smp_apmu_boot_secondary(unsigned int cpu, struct task_struct *idle) return apmu_wrap(cpu, apmu_power_on); } +#endif -#ifdef CONFIG_HOTPLUG_CPU +#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_SUSPEND) /* nicked from arch/arm/mach-exynos/hotplug.c */ static inline void cpu_enter_lowpower_a15(void) { @@ -172,16 +179,40 @@ static inline void cpu_enter_lowpower_a15(void) dsb(); } -void shmobile_smp_apmu_cpu_die(unsigned int cpu) +void shmobile_smp_apmu_cpu_shutdown(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(); +} + +static inline void cpu_leave_lowpower(void) +{ + unsigned int v; + + asm volatile("mrc p15, 0, %0, c1, c0, 0\n" + " orr %0, %0, %1\n" + " mcr p15, 0, %0, c1, c0, 0\n" + " mrc p15, 0, %0, c1, c0, 1\n" + " orr %0, %0, %2\n" + " mcr p15, 0, %0, c1, c0, 1\n" + : "=&r" (v) + : "Ir" (CR_C), "Ir" (0x40) + : "cc"); +} +#endif + +#if defined(CONFIG_HOTPLUG_CPU) +void shmobile_smp_apmu_cpu_die(unsigned int cpu) +{ + /* For this particular CPU deregister boot vector */ + shmobile_smp_hook(cpu, 0, 0); + + /* Shutdown CPU core */ + shmobile_smp_apmu_cpu_shutdown(cpu); /* jump to shared mach-shmobile sleep / reset code */ shmobile_smp_sleep(); @@ -192,3 +223,25 @@ int shmobile_smp_apmu_cpu_kill(unsigned int cpu) return apmu_wrap(cpu, apmu_power_off_poll); } #endif + +#if defined(CONFIG_SUSPEND) +static int shmobile_smp_apmu_do_suspend(unsigned long cpu) +{ + shmobile_smp_hook(cpu, virt_to_phys(cpu_resume), 0); + shmobile_smp_apmu_cpu_shutdown(cpu); + cpu_do_idle(); /* WFI selects Core Standby */ + return 1; +} + +static int shmobile_smp_apmu_enter_suspend(suspend_state_t state) +{ + cpu_suspend(smp_processor_id(), shmobile_smp_apmu_do_suspend); + cpu_leave_lowpower(); + return 0; +} + +void __init shmobile_smp_apmu_suspend_init(void) +{ + shmobile_suspend_ops.enter = shmobile_smp_apmu_enter_suspend; +} +#endif diff --git a/arch/arm/mach-shmobile/pm-r8a7779.c b/arch/arm/mach-shmobile/pm-r8a7779.c index f0f36cb5ffe7..69f70b7f7fb2 100644 --- a/arch/arm/mach-shmobile/pm-r8a7779.c +++ b/arch/arm/mach-shmobile/pm-r8a7779.c @@ -19,10 +19,12 @@ #include <linux/irq.h> #include <linux/interrupt.h> #include <linux/console.h> + #include <asm/io.h> -#include <mach/r8a7779.h> + #include "common.h" #include "pm-rcar.h" +#include "r8a7779.h" /* SYSC */ #define SYSCIER 0x0c diff --git a/arch/arm/mach-shmobile/pm-r8a7790.c b/arch/arm/mach-shmobile/pm-r8a7790.c index 8845433a00b3..80e8d95e54d3 100644 --- a/arch/arm/mach-shmobile/pm-r8a7790.c +++ b/arch/arm/mach-shmobile/pm-r8a7790.c @@ -11,12 +11,22 @@ */ #include <linux/kernel.h> - +#include <linux/smp.h> #include <asm/io.h> - +#include "common.h" #include "pm-rcar.h" #include "r8a7790.h" +/* RST */ +#define RST 0xe6160000 +#define CA15BAR 0x0020 +#define CA7BAR 0x0030 +#define CA15RESCNT 0x0040 +#define CA7RESCNT 0x0044 + +/* On-chip RAM */ +#define MERAM 0xe8080000 + /* SYSC */ #define SYSCIER 0x0c #define SYSCIMR 0x10 @@ -40,8 +50,33 @@ static inline void r8a7790_sysc_init(void) {} void __init r8a7790_pm_init(void) { + void __iomem *p; + u32 bar; static int once; - if (!once++) - r8a7790_sysc_init(); + if (once++) + return; + + /* 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); + + /* de-assert reset for all CPUs */ + writel_relaxed((readl_relaxed(p + CA15RESCNT) & ~0x0f) | 0xa5a50000, + p + CA15RESCNT); + writel_relaxed((readl_relaxed(p + CA7RESCNT) & ~0x0f) | 0x5a5a0000, + p + CA7RESCNT); + iounmap(p); + + r8a7790_sysc_init(); + shmobile_smp_apmu_suspend_init(); } diff --git a/arch/arm/mach-shmobile/pm-r8a7791.c b/arch/arm/mach-shmobile/pm-r8a7791.c new file mode 100644 index 000000000000..25f107bb3657 --- /dev/null +++ b/arch/arm/mach-shmobile/pm-r8a7791.c @@ -0,0 +1,73 @@ +/* + * r8a7791 Power management support + * + * Copyright (C) 2014 Renesas Electronics Corporation + * Copyright (C) 2011 Renesas Solutions Corp. + * Copyright (C) 2011 Magnus Damm + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/kernel.h> +#include <linux/smp.h> +#include <asm/io.h> +#include "common.h" +#include "pm-rcar.h" +#include "r8a7791.h" + +#define RST 0xe6160000 +#define CA15BAR 0x0020 +#define CA15RESCNT 0x0040 +#define RAM 0xe6300000 + +/* SYSC */ +#define SYSCIER 0x0c +#define SYSCIMR 0x10 + +#if defined(CONFIG_SMP) + +static void __init r8a7791_sysc_init(void) +{ + void __iomem *base = rcar_sysc_init(0xe6180000); + + /* enable all interrupt sources, but do not use interrupt handler */ + iowrite32(0x0131000e, base + SYSCIER); + iowrite32(0, base + SYSCIMR); +} + +#else /* CONFIG_SMP */ + +static inline void r8a7791_sysc_init(void) {} + +#endif /* CONFIG_SMP */ + +void __init r8a7791_pm_init(void) +{ + void __iomem *p; + u32 bar; + static int once; + + if (once++) + return; + + /* 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); + + r8a7791_sysc_init(); + shmobile_smp_apmu_suspend_init(); +} diff --git a/arch/arm/mach-shmobile/include/mach/r8a7779.h b/arch/arm/mach-shmobile/r8a7779.h index def10a29e09a..5415c719dc19 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7779.h +++ b/arch/arm/mach-shmobile/r8a7779.h @@ -10,7 +10,6 @@ enum { HPBDMA_SLAVE_SDHI0_RX, }; -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); @@ -20,6 +19,7 @@ extern void r8a7779_add_early_devices(void); extern void r8a7779_add_standard_devices(void); extern void r8a7779_add_standard_devices_dt(void); extern void r8a7779_init_late(void); +extern u32 r8a7779_read_mode_pins(void); extern void r8a7779_clock_init(void); extern void r8a7779_pinmux_init(void); extern void r8a7779_pm_init(void); diff --git a/arch/arm/mach-shmobile/include/mach/r8a7791.h b/arch/arm/mach-shmobile/r8a7791.h index 664274cc4b64..86eae7bceb6f 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7791.h +++ b/arch/arm/mach-shmobile/r8a7791.h @@ -5,6 +5,7 @@ void r8a7791_add_standard_devices(void); void r8a7791_add_dt_devices(void); void r8a7791_clock_init(void); void r8a7791_pinmux_init(void); +void r8a7791_pm_init(void); extern struct smp_operations r8a7791_smp_ops; #endif /* __ASM_R8A7791_H__ */ diff --git a/arch/arm/mach-shmobile/rcar-gen2.h b/arch/arm/mach-shmobile/rcar-gen2.h index 43f606eb2d82..ce53cb5f53a1 100644 --- a/arch/arm/mach-shmobile/rcar-gen2.h +++ b/arch/arm/mach-shmobile/rcar-gen2.h @@ -4,5 +4,6 @@ void rcar_gen2_timer_init(void); #define MD(nr) BIT(nr) u32 rcar_gen2_read_mode_pins(void); +void rcar_gen2_reserve(void); #endif /* __ASM_RCAR_GEN2_H__ */ diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c index 280303cef702..236c1befb9e3 100644 --- a/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/arch/arm/mach-shmobile/setup-r8a7779.c @@ -40,14 +40,16 @@ #include <linux/usb/ehci_pdriver.h> #include <linux/usb/ohci_pdriver.h> #include <linux/pm_runtime.h> -#include <mach/r8a7779.h> + #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/time.h> #include <asm/mach/map.h> #include <asm/hardware/cache-l2x0.h> + #include "common.h" #include "irqs.h" +#include "r8a7779.h" static struct map_desc r8a7779_io_desc[] __initdata = { /* 2M entity map for 0xf0000000 (MPCORE) */ @@ -640,16 +642,16 @@ static void __init r8a7779_register_hpb_dmae(void) } static struct platform_device *r8a7779_devices_dt[] __initdata = { + &tmu0_device, +}; + +static struct platform_device *r8a7779_standard_devices[] __initdata = { &scif0_device, &scif1_device, &scif2_device, &scif3_device, &scif4_device, &scif5_device, - &tmu0_device, -}; - -static struct platform_device *r8a7779_standard_devices[] __initdata = { &i2c0_device, &i2c1_device, &i2c2_device, @@ -674,16 +676,6 @@ void __init r8a7779_add_standard_devices(void) r8a7779_register_hpb_dmae(); } -/* do nothing for !CONFIG_SMP or !CONFIG_HAVE_TWD */ -void __init __weak r8a7779_register_twd(void) { } - -void __init r8a7779_earlytimer_init(void) -{ - r8a7779_clock_init(); - r8a7779_register_twd(); - shmobile_earlytimer_init(); -} - void __init r8a7779_add_early_devices(void) { early_platform_add_devices(r8a7779_devices_dt, @@ -747,19 +739,28 @@ void __init r8a7779_init_irq_dt(void) __raw_writel(0x003fee3f, INT2SMSKCR4); } -void __init r8a7779_init_delay(void) +void __init r8a7779_add_standard_devices_dt(void) { - shmobile_setup_delay(1000, 2, 4); /* Cortex-A9 @ 1000MHz */ + platform_add_devices(r8a7779_devices_dt, + ARRAY_SIZE(r8a7779_devices_dt)); } -void __init r8a7779_add_standard_devices_dt(void) +#define MODEMR 0xffcc0020 + +u32 __init r8a7779_read_mode_pins(void) { - /* clocks are setup late during boot in the case of DT */ - r8a7779_clock_init(); + static u32 mode; + static bool mode_valid; + + if (!mode_valid) { + void __iomem *modemr = ioremap_nocache(MODEMR, PAGE_SIZE); + BUG_ON(!modemr); + mode = ioread32(modemr); + iounmap(modemr); + mode_valid = true; + } - platform_add_devices(r8a7779_devices_dt, - ARRAY_SIZE(r8a7779_devices_dt)); - of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + return mode; } static const char *r8a7779_compat_dt[] __initdata = { @@ -769,7 +770,7 @@ static const char *r8a7779_compat_dt[] __initdata = { DT_MACHINE_START(R8A7779_DT, "Generic R8A7779 (Flattened Device Tree)") .map_io = r8a7779_map_io, - .init_early = r8a7779_init_delay, + .init_early = shmobile_init_delay, .nr_irqs = NR_IRQS_LEGACY, .init_irq = r8a7779_init_irq_dt, .init_machine = r8a7779_add_standard_devices_dt, diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c index 240411b42424..0c12b01bb9e3 100644 --- a/arch/arm/mach-shmobile/setup-r8a7790.c +++ b/arch/arm/mach-shmobile/setup-r8a7790.c @@ -321,6 +321,8 @@ DT_MACHINE_START(R8A7790_DT, "Generic R8A7790 (Flattened Device Tree)") .smp = smp_ops(r8a7790_smp_ops), .init_early = shmobile_init_delay, .init_time = rcar_gen2_timer_init, + .init_late = shmobile_init_late, + .reserve = rcar_gen2_reserve, .dt_compat = r8a7790_boards_compat_dt, MACHINE_END #endif /* CONFIG_USE_OF */ diff --git a/arch/arm/mach-shmobile/setup-r8a7791.c b/arch/arm/mach-shmobile/setup-r8a7791.c index 004b11a8fd88..d47d8b16a43f 100644 --- a/arch/arm/mach-shmobile/setup-r8a7791.c +++ b/arch/arm/mach-shmobile/setup-r8a7791.c @@ -26,10 +26,12 @@ #include <linux/platform_data/irq-renesas-irqc.h> #include <linux/serial_sci.h> #include <linux/sh_timer.h> -#include <mach/r8a7791.h> + #include <asm/mach/arch.h> + #include "common.h" #include "irqs.h" +#include "r8a7791.h" #include "rcar-gen2.h" static const struct resource pfc_resources[] __initconst = { @@ -217,6 +219,8 @@ DT_MACHINE_START(R8A7791_DT, "Generic R8A7791 (Flattened Device Tree)") .smp = smp_ops(r8a7791_smp_ops), .init_early = shmobile_init_delay, .init_time = rcar_gen2_timer_init, + .init_late = shmobile_init_late, + .reserve = rcar_gen2_reserve, .dt_compat = r8a7791_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 index fdc714ebc4cd..42d5b4308923 100644 --- a/arch/arm/mach-shmobile/setup-rcar-gen2.c +++ b/arch/arm/mach-shmobile/setup-rcar-gen2.c @@ -20,8 +20,11 @@ #include <linux/clk/shmobile.h> #include <linux/clocksource.h> +#include <linux/device.h> +#include <linux/dma-contiguous.h> #include <linux/io.h> #include <linux/kernel.h> +#include <linux/of_fdt.h> #include <asm/mach/arch.h> #include "common.h" #include "rcar-gen2.h" @@ -110,3 +113,72 @@ void __init rcar_gen2_timer_init(void) #endif clocksource_of_init(); } + +struct memory_reserve_config { + u64 reserved; + u64 base, size; +}; + +static int __init rcar_gen2_scan_mem(unsigned long node, const char *uname, + int depth, void *data) +{ + const char *type = of_get_flat_dt_prop(node, "device_type", NULL); + const __be32 *reg, *endp; + int l; + struct memory_reserve_config *mrc = data; + u64 lpae_start = 1ULL << 32; + + /* We are scanning "memory" nodes only */ + if (type == NULL || strcmp(type, "memory")) + return 0; + + reg = of_get_flat_dt_prop(node, "linux,usable-memory", &l); + if (reg == NULL) + reg = of_get_flat_dt_prop(node, "reg", &l); + if (reg == NULL) + return 0; + + endp = reg + (l / sizeof(__be32)); + while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) { + u64 base, size; + + base = dt_mem_next_cell(dt_root_addr_cells, ®); + size = dt_mem_next_cell(dt_root_size_cells, ®); + + if (base >= lpae_start) + continue; + + if ((base + size) >= lpae_start) + size = lpae_start - base; + + if (size < mrc->reserved) + continue; + + if (base < mrc->base) + continue; + + /* keep the area at top near the 32-bit legacy limit */ + mrc->base = base + size - mrc->reserved; + mrc->size = mrc->reserved; + } + + return 0; +} + +struct cma *rcar_gen2_dma_contiguous; + +void __init rcar_gen2_reserve(void) +{ + struct memory_reserve_config mrc; + + /* reserve 256 MiB at the top of the physical legacy 32-bit space */ + memset(&mrc, 0, sizeof(mrc)); + mrc.reserved = SZ_256M; + + of_scan_flat_dt(rcar_gen2_scan_mem, &mrc); +#ifdef CONFIG_DMA_CMA + if (mrc.size) + dma_contiguous_reserve_area(mrc.size, mrc.base, 0, + &rcar_gen2_dma_contiguous, true); +#endif +} diff --git a/arch/arm/mach-shmobile/smp-r8a7779.c b/arch/arm/mach-shmobile/smp-r8a7779.c index c230fc0c3fef..3100e355c3fd 100644 --- a/arch/arm/mach-shmobile/smp-r8a7779.c +++ b/arch/arm/mach-shmobile/smp-r8a7779.c @@ -23,13 +23,15 @@ #include <linux/spinlock.h> #include <linux/io.h> #include <linux/delay.h> -#include <mach/r8a7779.h> + #include <asm/cacheflush.h> #include <asm/smp_plat.h> #include <asm/smp_scu.h> #include <asm/smp_twd.h> + #include "common.h" #include "pm-rcar.h" +#include "r8a7779.h" #define AVECR IOMEM(0xfe700040) #define R8A7779_SCU_BASE 0xf0000000 diff --git a/arch/arm/mach-shmobile/smp-r8a7790.c b/arch/arm/mach-shmobile/smp-r8a7790.c index c256fdfbb5b0..2311694636e1 100644 --- a/arch/arm/mach-shmobile/smp-r8a7790.c +++ b/arch/arm/mach-shmobile/smp-r8a7790.c @@ -24,13 +24,6 @@ #include "pm-rcar.h" #include "r8a7790.h" -#define RST 0xe6160000 -#define CA15BAR 0x0020 -#define CA7BAR 0x0030 -#define CA15RESCNT 0x0040 -#define CA7RESCNT 0x0044 -#define MERAM 0xe8080000 - static struct rcar_sysc_ch r8a7790_ca15_scu = { .chan_offs = 0x180, /* PWRSR5 .. PWRER5 */ .isr_bit = 12, /* CA15-SCU */ @@ -43,32 +36,9 @@ static struct rcar_sysc_ch r8a7790_ca7_scu = { 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); - /* turn on power to SCU */ r8a7790_pm_init(); rcar_sysc_power_up(&r8a7790_ca15_scu); diff --git a/arch/arm/mach-shmobile/smp-r8a7791.c b/arch/arm/mach-shmobile/smp-r8a7791.c index 2648d68650e4..f743386166fb 100644 --- a/arch/arm/mach-shmobile/smp-r8a7791.c +++ b/arch/arm/mach-shmobile/smp-r8a7791.c @@ -17,39 +17,19 @@ #include <linux/init.h> #include <linux/smp.h> #include <linux/io.h> + #include <asm/smp_plat.h> -#include <mach/r8a7791.h> + #include "common.h" +#include "r8a7791.h" #include "rcar-gen2.h" -#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); + r8a7791_pm_init(); } static int r8a7791_smp_boot_secondary(unsigned int cpu, diff --git a/arch/arm/mach-shmobile/timer.c b/arch/arm/mach-shmobile/timer.c index 68bc0b82226d..942efdc82a62 100644 --- a/arch/arm/mach-shmobile/timer.c +++ b/arch/arm/mach-shmobile/timer.c @@ -59,29 +59,37 @@ void __init shmobile_setup_delay(unsigned int max_cpu_core_mhz, void __init shmobile_init_delay(void) { - struct device_node *np, *parent; - u32 max_freq, freq; - - max_freq = 0; - - parent = of_find_node_by_path("/cpus"); - if (parent) { - for_each_child_of_node(parent, np) { - if (!of_property_read_u32(np, "clock-frequency", &freq)) - max_freq = max(max_freq, freq); - } - of_node_put(parent); - } + struct device_node *np, *cpus; + bool is_a8_a9 = false; + bool is_a15 = false; + u32 max_freq = 0; + + cpus = of_find_node_by_path("/cpus"); + if (!cpus) + return; + + for_each_child_of_node(cpus, np) { + u32 freq; + + if (!of_property_read_u32(np, "clock-frequency", &freq)) + max_freq = max(max_freq, freq); - if (max_freq) { - if (of_find_compatible_node(NULL, NULL, "arm,cortex-a8")) - shmobile_setup_delay_hz(max_freq, 1, 3); - else if (of_find_compatible_node(NULL, NULL, "arm,cortex-a9")) - shmobile_setup_delay_hz(max_freq, 1, 3); - else if (of_find_compatible_node(NULL, NULL, "arm,cortex-a15")) - if (!IS_ENABLED(CONFIG_ARM_ARCH_TIMER)) - shmobile_setup_delay_hz(max_freq, 2, 4); + if (of_device_is_compatible(np, "arm,cortex-a8") || + of_device_is_compatible(np, "arm,cortex-a9")) + is_a8_a9 = true; + else if (of_device_is_compatible(np, "arm,cortex-a15")) + is_a15 = true; } + + of_node_put(cpus); + + if (!max_freq) + return; + + if (is_a8_a9) + shmobile_setup_delay_hz(max_freq, 1, 3); + else if (is_a15 && !IS_ENABLED(CONFIG_ARM_ARCH_TIMER)) + shmobile_setup_delay_hz(max_freq, 2, 4); } static void __init shmobile_late_time_init(void) |