| From 5124ae6b88ff9fe400999e1d43b9cbbd6dc85e15 Mon Sep 17 00:00:00 2001 |
| From: Magnus Damm <damm@opensource.se> |
| 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 <damm@opensource.se> |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| (cherry picked from commit 0086df273cf8c7e270f8930cc42d7dad15060516) |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| --- |
| 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 |
| |
| 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 eda285794961..6e7d0a9b0be9 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 623fa207520b..af9e0ee9bea7 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 <linux/init.h> |
| +#include <linux/kernel.h> |
| +#include <linux/io.h> |
| +#include <linux/sh_clk.h> |
| +#include <linux/clkdev.h> |
| +#include <mach/common.h> |
| +#include <mach/r7s72100.h> |
| + |
| +/* 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 <linux/irq.h> |
| +#include <linux/kernel.h> |
| +#include <linux/of_platform.h> |
| +#include <mach/common.h> |
| +#include <mach/r7s72100.h> |
| +#include <asm/mach/arch.h> |
| + |
| +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 */ |
| -- |
| 1.8.5.rc3 |
| |