From 1faf8692bdc2da1e12c7f2ecda3a9e629ac9b05b Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 3 May 2016 09:37:08 +0200 Subject: [PATCH 01/19] clk: renesas: cpg-mssr: Document r8a7796 support Signed-off-by: Geert Uytterhoeven Acked-by: Rob Herring Tested-by: Simon Horman --- .../devicetree/bindings/clock/renesas,cpg-mssr.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt index fefb8023020f..394d725ac7e0 100644 --- a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt @@ -13,7 +13,8 @@ They provide the following functionalities: Required Properties: - compatible: Must be one of: - - "renesas,r8a7795-cpg-mssr" for the r8a7795 SoC + - "renesas,r8a7795-cpg-mssr" for the r8a7795 SoC (R-Car H3) + - "renesas,r8a7796-cpg-mssr" for the r8a7796 SoC (R-Car M3-W) - reg: Base address and length of the memory resource used by the CPG/MSSR block @@ -21,8 +22,8 @@ Required Properties: - clocks: References to external parent clocks, one entry for each entry in clock-names - clock-names: List of external parent clock names. Valid names are: - - "extal" (r8a7795) - - "extalr" (r8a7795) + - "extal" (r8a7795, r8a7796) + - "extalr" (r8a7795, r8a7796) - #clock-cells: Must be 2 - For CPG core clocks, the two clock specifier cells must be "CPG_CORE" From 972610fb23b08dd54879102a9d5be695d53b728b Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 2 May 2016 14:36:32 +0200 Subject: [PATCH 02/19] clk: renesas: Add r8a7796 CPG Core Clock Definitions Add all R-Car M3-W Clock Pulse Generator Core Clock Outputs, as listed in Table 8.2b ("List of Clocks [R-Car M3-W]") of the R-Car Gen3 datasheet (rev. 0.51 + Errata for Rev051 Mar 31 2016). Note that internal CPG clocks (S0, S1, S2, S3, SDSRC, and SSPSRC) are not included, as they are used as internal clock sources only, and never referenced from DT. Signed-off-by: Geert Uytterhoeven Tested-by: Simon Horman --- include/dt-bindings/clock/r8a7796-cpg-mssr.h | 69 ++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 include/dt-bindings/clock/r8a7796-cpg-mssr.h diff --git a/include/dt-bindings/clock/r8a7796-cpg-mssr.h b/include/dt-bindings/clock/r8a7796-cpg-mssr.h new file mode 100644 index 000000000000..1e5942695f0d --- /dev/null +++ b/include/dt-bindings/clock/r8a7796-cpg-mssr.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2016 Renesas Electronics Corp. + * + * 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; either version 2 of the License, or + * (at your option) any later version. + */ +#ifndef __DT_BINDINGS_CLOCK_R8A7796_CPG_MSSR_H__ +#define __DT_BINDINGS_CLOCK_R8A7796_CPG_MSSR_H__ + +#include + +/* r8a7796 CPG Core Clocks */ +#define R8A7796_CLK_Z 0 +#define R8A7796_CLK_Z2 1 +#define R8A7796_CLK_ZR 2 +#define R8A7796_CLK_ZG 3 +#define R8A7796_CLK_ZTR 4 +#define R8A7796_CLK_ZTRD2 5 +#define R8A7796_CLK_ZT 6 +#define R8A7796_CLK_ZX 7 +#define R8A7796_CLK_S0D1 8 +#define R8A7796_CLK_S0D2 9 +#define R8A7796_CLK_S0D3 10 +#define R8A7796_CLK_S0D4 11 +#define R8A7796_CLK_S0D6 12 +#define R8A7796_CLK_S0D8 13 +#define R8A7796_CLK_S0D12 14 +#define R8A7796_CLK_S1D1 15 +#define R8A7796_CLK_S1D2 16 +#define R8A7796_CLK_S1D4 17 +#define R8A7796_CLK_S2D1 18 +#define R8A7796_CLK_S2D2 19 +#define R8A7796_CLK_S2D4 20 +#define R8A7796_CLK_S3D1 21 +#define R8A7796_CLK_S3D2 22 +#define R8A7796_CLK_S3D4 23 +#define R8A7796_CLK_LB 24 +#define R8A7796_CLK_CL 25 +#define R8A7796_CLK_ZB3 26 +#define R8A7796_CLK_ZB3D2 27 +#define R8A7796_CLK_ZB3D4 28 +#define R8A7796_CLK_CR 29 +#define R8A7796_CLK_CRD2 30 +#define R8A7796_CLK_SD0H 31 +#define R8A7796_CLK_SD0 32 +#define R8A7796_CLK_SD1H 33 +#define R8A7796_CLK_SD1 34 +#define R8A7796_CLK_SD2H 35 +#define R8A7796_CLK_SD2 36 +#define R8A7796_CLK_SD3H 37 +#define R8A7796_CLK_SD3 38 +#define R8A7796_CLK_SSP2 39 +#define R8A7796_CLK_SSP1 40 +#define R8A7796_CLK_SSPRS 41 +#define R8A7796_CLK_RPC 42 +#define R8A7796_CLK_RPCD2 43 +#define R8A7796_CLK_MSO 44 +#define R8A7796_CLK_CANFD 45 +#define R8A7796_CLK_HDMI 46 +#define R8A7796_CLK_CSI0 47 +#define R8A7796_CLK_CSIREF 48 +#define R8A7796_CLK_CP 49 +#define R8A7796_CLK_CPEX 50 +#define R8A7796_CLK_R 51 +#define R8A7796_CLK_OSC 52 + +#endif /* __DT_BINDINGS_CLOCK_R8A7796_CPG_MSSR_H__ */ From 5b1defde7054e66da5c0f6cba8b35cef29edede0 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 4 May 2016 14:32:56 +0200 Subject: [PATCH 03/19] clk: renesas: cpg-mssr: Extract common R-Car Gen3 support code Extract the code to support parts common to all members of the R-Car Gen3 SoC family into a separate file, to ease sharing among SoC-specific drivers. Note that while the cpg_pll_configs[] arrays and the selection of the config based on the MODE bits are identical on R-Car H3 and R-Car M3-W, they are not common, and may be different on other R-Car Gen3 SoCs. Signed-off-by: Geert Uytterhoeven Tested-by: Simon Horman --- drivers/clk/renesas/Makefile | 2 +- drivers/clk/renesas/r8a7795-cpg-mssr.c | 360 +------------------------ drivers/clk/renesas/rcar-gen3-cpg.c | 359 ++++++++++++++++++++++++ drivers/clk/renesas/rcar-gen3-cpg.h | 43 +++ 4 files changed, 408 insertions(+), 356 deletions(-) create mode 100644 drivers/clk/renesas/rcar-gen3-cpg.c create mode 100644 drivers/clk/renesas/rcar-gen3-cpg.h diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index ead8bb843524..88924c95808c 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -8,7 +8,7 @@ obj-$(CONFIG_ARCH_R8A7790) += clk-rcar-gen2.o clk-div6.o obj-$(CONFIG_ARCH_R8A7791) += clk-rcar-gen2.o clk-div6.o obj-$(CONFIG_ARCH_R8A7793) += clk-rcar-gen2.o clk-div6.o obj-$(CONFIG_ARCH_R8A7794) += clk-rcar-gen2.o clk-div6.o -obj-$(CONFIG_ARCH_R8A7795) += r8a7795-cpg-mssr.o +obj-$(CONFIG_ARCH_R8A7795) += r8a7795-cpg-mssr.o rcar-gen3-cpg.o obj-$(CONFIG_ARCH_SH73A0) += clk-sh73a0.o clk-div6.o obj-$(CONFIG_CLK_RENESAS_CPG_MSSR) += renesas-cpg-mssr.o clk-div6.o diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c index ca5519c583d4..e53aff5b23ad 100644 --- a/drivers/clk/renesas/r8a7795-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c @@ -12,22 +12,14 @@ * the Free Software Foundation; version 2 of the License. */ -#include -#include -#include #include -#include #include -#include #include -#include -#include #include #include "renesas-cpg-mssr.h" - -#define CPG_RCKCR 0x240 +#include "rcar-gen3-cpg.h" enum clk_ids { /* Core Clock Outputs exported to DT */ @@ -58,20 +50,6 @@ enum clk_ids { MOD_CLK_BASE }; -enum r8a7795_clk_types { - CLK_TYPE_GEN3_MAIN = CLK_TYPE_CUSTOM, - CLK_TYPE_GEN3_PLL0, - CLK_TYPE_GEN3_PLL1, - CLK_TYPE_GEN3_PLL2, - CLK_TYPE_GEN3_PLL3, - CLK_TYPE_GEN3_PLL4, - CLK_TYPE_GEN3_SD, - CLK_TYPE_GEN3_R, -}; - -#define DEF_GEN3_SD(_name, _id, _parent, _offset) \ - DEF_BASE(_name, _id, CLK_TYPE_GEN3_SD, _parent, .offset = _offset) - static const struct cpg_core_clk r8a7795_core_clks[] __initconst = { /* External Clock Inputs */ DEF_INPUT("extal", CLK_EXTAL), @@ -262,225 +240,6 @@ static const unsigned int r8a7795_crit_mod_clks[] __initconst = { MOD_CLK_ID(408), /* INTC-AP (GIC) */ }; -/* ----------------------------------------------------------------------------- - * SDn Clock - * - */ -#define CPG_SD_STP_HCK BIT(9) -#define CPG_SD_STP_CK BIT(8) - -#define CPG_SD_STP_MASK (CPG_SD_STP_HCK | CPG_SD_STP_CK) -#define CPG_SD_FC_MASK (0x7 << 2 | 0x3 << 0) - -#define CPG_SD_DIV_TABLE_DATA(stp_hck, stp_ck, sd_srcfc, sd_fc, sd_div) \ -{ \ - .val = ((stp_hck) ? CPG_SD_STP_HCK : 0) | \ - ((stp_ck) ? CPG_SD_STP_CK : 0) | \ - ((sd_srcfc) << 2) | \ - ((sd_fc) << 0), \ - .div = (sd_div), \ -} - -struct sd_div_table { - u32 val; - unsigned int div; -}; - -struct sd_clock { - struct clk_hw hw; - void __iomem *reg; - const struct sd_div_table *div_table; - unsigned int div_num; - unsigned int div_min; - unsigned int div_max; -}; - -/* SDn divider - * sd_srcfc sd_fc div - * stp_hck stp_ck (div) (div) = sd_srcfc x sd_fc - *------------------------------------------------------------------- - * 0 0 0 (1) 1 (4) 4 - * 0 0 1 (2) 1 (4) 8 - * 1 0 2 (4) 1 (4) 16 - * 1 0 3 (8) 1 (4) 32 - * 1 0 4 (16) 1 (4) 64 - * 0 0 0 (1) 0 (2) 2 - * 0 0 1 (2) 0 (2) 4 - * 1 0 2 (4) 0 (2) 8 - * 1 0 3 (8) 0 (2) 16 - * 1 0 4 (16) 0 (2) 32 - */ -static const struct sd_div_table cpg_sd_div_table[] = { -/* CPG_SD_DIV_TABLE_DATA(stp_hck, stp_ck, sd_srcfc, sd_fc, sd_div) */ - CPG_SD_DIV_TABLE_DATA(0, 0, 0, 1, 4), - CPG_SD_DIV_TABLE_DATA(0, 0, 1, 1, 8), - CPG_SD_DIV_TABLE_DATA(1, 0, 2, 1, 16), - CPG_SD_DIV_TABLE_DATA(1, 0, 3, 1, 32), - CPG_SD_DIV_TABLE_DATA(1, 0, 4, 1, 64), - CPG_SD_DIV_TABLE_DATA(0, 0, 0, 0, 2), - CPG_SD_DIV_TABLE_DATA(0, 0, 1, 0, 4), - CPG_SD_DIV_TABLE_DATA(1, 0, 2, 0, 8), - CPG_SD_DIV_TABLE_DATA(1, 0, 3, 0, 16), - CPG_SD_DIV_TABLE_DATA(1, 0, 4, 0, 32), -}; - -#define to_sd_clock(_hw) container_of(_hw, struct sd_clock, hw) - -static int cpg_sd_clock_enable(struct clk_hw *hw) -{ - struct sd_clock *clock = to_sd_clock(hw); - u32 val, sd_fc; - unsigned int i; - - val = clk_readl(clock->reg); - - sd_fc = val & CPG_SD_FC_MASK; - for (i = 0; i < clock->div_num; i++) - if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK)) - break; - - if (i >= clock->div_num) - return -EINVAL; - - val &= ~(CPG_SD_STP_MASK); - val |= clock->div_table[i].val & CPG_SD_STP_MASK; - - clk_writel(val, clock->reg); - - return 0; -} - -static void cpg_sd_clock_disable(struct clk_hw *hw) -{ - struct sd_clock *clock = to_sd_clock(hw); - - clk_writel(clk_readl(clock->reg) | CPG_SD_STP_MASK, clock->reg); -} - -static int cpg_sd_clock_is_enabled(struct clk_hw *hw) -{ - struct sd_clock *clock = to_sd_clock(hw); - - return !(clk_readl(clock->reg) & CPG_SD_STP_MASK); -} - -static unsigned long cpg_sd_clock_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct sd_clock *clock = to_sd_clock(hw); - unsigned long rate = parent_rate; - u32 val, sd_fc; - unsigned int i; - - val = clk_readl(clock->reg); - - sd_fc = val & CPG_SD_FC_MASK; - for (i = 0; i < clock->div_num; i++) - if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK)) - break; - - if (i >= clock->div_num) - return -EINVAL; - - return DIV_ROUND_CLOSEST(rate, clock->div_table[i].div); -} - -static unsigned int cpg_sd_clock_calc_div(struct sd_clock *clock, - unsigned long rate, - unsigned long parent_rate) -{ - unsigned int div; - - if (!rate) - rate = 1; - - div = DIV_ROUND_CLOSEST(parent_rate, rate); - - return clamp_t(unsigned int, div, clock->div_min, clock->div_max); -} - -static long cpg_sd_clock_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) -{ - struct sd_clock *clock = to_sd_clock(hw); - unsigned int div = cpg_sd_clock_calc_div(clock, rate, *parent_rate); - - return DIV_ROUND_CLOSEST(*parent_rate, div); -} - -static int cpg_sd_clock_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct sd_clock *clock = to_sd_clock(hw); - unsigned int div = cpg_sd_clock_calc_div(clock, rate, parent_rate); - u32 val; - unsigned int i; - - for (i = 0; i < clock->div_num; i++) - if (div == clock->div_table[i].div) - break; - - if (i >= clock->div_num) - return -EINVAL; - - val = clk_readl(clock->reg); - val &= ~(CPG_SD_STP_MASK | CPG_SD_FC_MASK); - val |= clock->div_table[i].val & (CPG_SD_STP_MASK | CPG_SD_FC_MASK); - clk_writel(val, clock->reg); - - return 0; -} - -static const struct clk_ops cpg_sd_clock_ops = { - .enable = cpg_sd_clock_enable, - .disable = cpg_sd_clock_disable, - .is_enabled = cpg_sd_clock_is_enabled, - .recalc_rate = cpg_sd_clock_recalc_rate, - .round_rate = cpg_sd_clock_round_rate, - .set_rate = cpg_sd_clock_set_rate, -}; - -static struct clk * __init cpg_sd_clk_register(const struct cpg_core_clk *core, - void __iomem *base, - const char *parent_name) -{ - struct clk_init_data init; - struct sd_clock *clock; - struct clk *clk; - unsigned int i; - - clock = kzalloc(sizeof(*clock), GFP_KERNEL); - if (!clock) - return ERR_PTR(-ENOMEM); - - init.name = core->name; - init.ops = &cpg_sd_clock_ops; - init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; - init.parent_names = &parent_name; - init.num_parents = 1; - - clock->reg = base + core->offset; - clock->hw.init = &init; - clock->div_table = cpg_sd_div_table; - clock->div_num = ARRAY_SIZE(cpg_sd_div_table); - - clock->div_max = clock->div_table[0].div; - clock->div_min = clock->div_max; - for (i = 1; i < clock->div_num; i++) { - clock->div_max = max(clock->div_max, clock->div_table[i].div); - clock->div_min = min(clock->div_min, clock->div_table[i].div); - } - - clk = clk_register(NULL, &clock->hw); - if (IS_ERR(clk)) - kfree(clock); - - return clk; -} - -#define CPG_PLL0CR 0x00d8 -#define CPG_PLL2CR 0x002c -#define CPG_PLL4CR 0x01f4 /* * CPG Clock Data @@ -512,13 +271,7 @@ static struct clk * __init cpg_sd_clk_register(const struct cpg_core_clk *core, (((md) & BIT(19)) >> 18) | \ (((md) & BIT(17)) >> 17)) -struct cpg_pll_config { - unsigned int extal_div; - unsigned int pll1_mult; - unsigned int pll3_mult; -}; - -static const struct cpg_pll_config cpg_pll_configs[16] __initconst = { +static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] __initconst = { /* EXTAL div PLL1 mult PLL3 mult */ { 1, 192, 192, }, { 1, 192, 128, }, @@ -538,112 +291,9 @@ static const struct cpg_pll_config cpg_pll_configs[16] __initconst = { { 2, 192, 192, }, }; -static const struct cpg_pll_config *cpg_pll_config __initdata; - -static -struct clk * __init r8a7795_cpg_clk_register(struct device *dev, - const struct cpg_core_clk *core, - const struct cpg_mssr_info *info, - struct clk **clks, - void __iomem *base) -{ - const struct clk *parent; - unsigned int mult = 1; - unsigned int div = 1; - u32 value; - - parent = clks[core->parent]; - if (IS_ERR(parent)) - return ERR_CAST(parent); - - switch (core->type) { - case CLK_TYPE_GEN3_MAIN: - div = cpg_pll_config->extal_div; - break; - - case CLK_TYPE_GEN3_PLL0: - /* - * PLL0 is a configurable multiplier clock. Register it as a - * fixed factor clock for now as there's no generic multiplier - * clock implementation and we currently have no need to change - * the multiplier value. - */ - value = readl(base + CPG_PLL0CR); - mult = (((value >> 24) & 0x7f) + 1) * 2; - break; - - case CLK_TYPE_GEN3_PLL1: - mult = cpg_pll_config->pll1_mult; - break; - - case CLK_TYPE_GEN3_PLL2: - /* - * PLL2 is a configurable multiplier clock. Register it as a - * fixed factor clock for now as there's no generic multiplier - * clock implementation and we currently have no need to change - * the multiplier value. - */ - value = readl(base + CPG_PLL2CR); - mult = (((value >> 24) & 0x7f) + 1) * 2; - break; - - case CLK_TYPE_GEN3_PLL3: - mult = cpg_pll_config->pll3_mult; - break; - - case CLK_TYPE_GEN3_PLL4: - /* - * PLL4 is a configurable multiplier clock. Register it as a - * fixed factor clock for now as there's no generic multiplier - * clock implementation and we currently have no need to change - * the multiplier value. - */ - value = readl(base + CPG_PLL4CR); - mult = (((value >> 24) & 0x7f) + 1) * 2; - break; - - case CLK_TYPE_GEN3_SD: - return cpg_sd_clk_register(core, base, __clk_get_name(parent)); - - case CLK_TYPE_GEN3_R: - /* RINT is default. Only if EXTALR is populated, we switch to it */ - value = readl(base + CPG_RCKCR) & 0x3f; - - if (clk_get_rate(clks[CLK_EXTALR])) { - parent = clks[CLK_EXTALR]; - value |= BIT(15); - } - - writel(value, base + CPG_RCKCR); - break; - - default: - return ERR_PTR(-EINVAL); - } - - return clk_register_fixed_factor(NULL, core->name, - __clk_get_name(parent), 0, mult, div); -} - -/* - * Reset register definitions. - */ -#define MODEMR 0xe6160060 - -static u32 rcar_gen3_read_mode_pins(void) -{ - void __iomem *modemr = ioremap_nocache(MODEMR, 4); - u32 mode; - - BUG_ON(!modemr); - mode = ioread32(modemr); - iounmap(modemr); - - return mode; -} - static int __init r8a7795_cpg_mssr_init(struct device *dev) { + const struct rcar_gen3_cpg_pll_config *cpg_pll_config; u32 cpg_mode = rcar_gen3_read_mode_pins(); cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)]; @@ -652,7 +302,7 @@ static int __init r8a7795_cpg_mssr_init(struct device *dev) return -EINVAL; } - return 0; + return rcar_gen3_cpg_init(cpg_pll_config, CLK_EXTALR); } const struct cpg_mssr_info r8a7795_cpg_mssr_info __initconst = { @@ -673,5 +323,5 @@ const struct cpg_mssr_info r8a7795_cpg_mssr_info __initconst = { /* Callbacks */ .init = r8a7795_cpg_mssr_init, - .cpg_clk_register = r8a7795_cpg_clk_register, + .cpg_clk_register = rcar_gen3_cpg_clk_register, }; diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c new file mode 100644 index 000000000000..bb4f2f9a8c2f --- /dev/null +++ b/drivers/clk/renesas/rcar-gen3-cpg.c @@ -0,0 +1,359 @@ +/* + * R-Car Gen3 Clock Pulse Generator + * + * Copyright (C) 2015-2016 Glider bvba + * + * Based on clk-rcar-gen3.c + * + * Copyright (C) 2015 Renesas Electronics Corp. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "renesas-cpg-mssr.h" +#include "rcar-gen3-cpg.h" + +#define CPG_PLL0CR 0x00d8 +#define CPG_PLL2CR 0x002c +#define CPG_PLL4CR 0x01f4 + + +/* + * SDn Clock + */ +#define CPG_SD_STP_HCK BIT(9) +#define CPG_SD_STP_CK BIT(8) + +#define CPG_SD_STP_MASK (CPG_SD_STP_HCK | CPG_SD_STP_CK) +#define CPG_SD_FC_MASK (0x7 << 2 | 0x3 << 0) + +#define CPG_SD_DIV_TABLE_DATA(stp_hck, stp_ck, sd_srcfc, sd_fc, sd_div) \ +{ \ + .val = ((stp_hck) ? CPG_SD_STP_HCK : 0) | \ + ((stp_ck) ? CPG_SD_STP_CK : 0) | \ + ((sd_srcfc) << 2) | \ + ((sd_fc) << 0), \ + .div = (sd_div), \ +} + +struct sd_div_table { + u32 val; + unsigned int div; +}; + +struct sd_clock { + struct clk_hw hw; + void __iomem *reg; + const struct sd_div_table *div_table; + unsigned int div_num; + unsigned int div_min; + unsigned int div_max; +}; + +/* SDn divider + * sd_srcfc sd_fc div + * stp_hck stp_ck (div) (div) = sd_srcfc x sd_fc + *------------------------------------------------------------------- + * 0 0 0 (1) 1 (4) 4 + * 0 0 1 (2) 1 (4) 8 + * 1 0 2 (4) 1 (4) 16 + * 1 0 3 (8) 1 (4) 32 + * 1 0 4 (16) 1 (4) 64 + * 0 0 0 (1) 0 (2) 2 + * 0 0 1 (2) 0 (2) 4 + * 1 0 2 (4) 0 (2) 8 + * 1 0 3 (8) 0 (2) 16 + * 1 0 4 (16) 0 (2) 32 + */ +static const struct sd_div_table cpg_sd_div_table[] = { +/* CPG_SD_DIV_TABLE_DATA(stp_hck, stp_ck, sd_srcfc, sd_fc, sd_div) */ + CPG_SD_DIV_TABLE_DATA(0, 0, 0, 1, 4), + CPG_SD_DIV_TABLE_DATA(0, 0, 1, 1, 8), + CPG_SD_DIV_TABLE_DATA(1, 0, 2, 1, 16), + CPG_SD_DIV_TABLE_DATA(1, 0, 3, 1, 32), + CPG_SD_DIV_TABLE_DATA(1, 0, 4, 1, 64), + CPG_SD_DIV_TABLE_DATA(0, 0, 0, 0, 2), + CPG_SD_DIV_TABLE_DATA(0, 0, 1, 0, 4), + CPG_SD_DIV_TABLE_DATA(1, 0, 2, 0, 8), + CPG_SD_DIV_TABLE_DATA(1, 0, 3, 0, 16), + CPG_SD_DIV_TABLE_DATA(1, 0, 4, 0, 32), +}; + +#define to_sd_clock(_hw) container_of(_hw, struct sd_clock, hw) + +static int cpg_sd_clock_enable(struct clk_hw *hw) +{ + struct sd_clock *clock = to_sd_clock(hw); + u32 val, sd_fc; + unsigned int i; + + val = clk_readl(clock->reg); + + sd_fc = val & CPG_SD_FC_MASK; + for (i = 0; i < clock->div_num; i++) + if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK)) + break; + + if (i >= clock->div_num) + return -EINVAL; + + val &= ~(CPG_SD_STP_MASK); + val |= clock->div_table[i].val & CPG_SD_STP_MASK; + + clk_writel(val, clock->reg); + + return 0; +} + +static void cpg_sd_clock_disable(struct clk_hw *hw) +{ + struct sd_clock *clock = to_sd_clock(hw); + + clk_writel(clk_readl(clock->reg) | CPG_SD_STP_MASK, clock->reg); +} + +static int cpg_sd_clock_is_enabled(struct clk_hw *hw) +{ + struct sd_clock *clock = to_sd_clock(hw); + + return !(clk_readl(clock->reg) & CPG_SD_STP_MASK); +} + +static unsigned long cpg_sd_clock_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct sd_clock *clock = to_sd_clock(hw); + unsigned long rate = parent_rate; + u32 val, sd_fc; + unsigned int i; + + val = clk_readl(clock->reg); + + sd_fc = val & CPG_SD_FC_MASK; + for (i = 0; i < clock->div_num; i++) + if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK)) + break; + + if (i >= clock->div_num) + return -EINVAL; + + return DIV_ROUND_CLOSEST(rate, clock->div_table[i].div); +} + +static unsigned int cpg_sd_clock_calc_div(struct sd_clock *clock, + unsigned long rate, + unsigned long parent_rate) +{ + unsigned int div; + + if (!rate) + rate = 1; + + div = DIV_ROUND_CLOSEST(parent_rate, rate); + + return clamp_t(unsigned int, div, clock->div_min, clock->div_max); +} + +static long cpg_sd_clock_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + struct sd_clock *clock = to_sd_clock(hw); + unsigned int div = cpg_sd_clock_calc_div(clock, rate, *parent_rate); + + return DIV_ROUND_CLOSEST(*parent_rate, div); +} + +static int cpg_sd_clock_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct sd_clock *clock = to_sd_clock(hw); + unsigned int div = cpg_sd_clock_calc_div(clock, rate, parent_rate); + u32 val; + unsigned int i; + + for (i = 0; i < clock->div_num; i++) + if (div == clock->div_table[i].div) + break; + + if (i >= clock->div_num) + return -EINVAL; + + val = clk_readl(clock->reg); + val &= ~(CPG_SD_STP_MASK | CPG_SD_FC_MASK); + val |= clock->div_table[i].val & (CPG_SD_STP_MASK | CPG_SD_FC_MASK); + clk_writel(val, clock->reg); + + return 0; +} + +static const struct clk_ops cpg_sd_clock_ops = { + .enable = cpg_sd_clock_enable, + .disable = cpg_sd_clock_disable, + .is_enabled = cpg_sd_clock_is_enabled, + .recalc_rate = cpg_sd_clock_recalc_rate, + .round_rate = cpg_sd_clock_round_rate, + .set_rate = cpg_sd_clock_set_rate, +}; + +static struct clk * __init cpg_sd_clk_register(const struct cpg_core_clk *core, + void __iomem *base, + const char *parent_name) +{ + struct clk_init_data init; + struct sd_clock *clock; + struct clk *clk; + unsigned int i; + + clock = kzalloc(sizeof(*clock), GFP_KERNEL); + if (!clock) + return ERR_PTR(-ENOMEM); + + init.name = core->name; + init.ops = &cpg_sd_clock_ops; + init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; + init.parent_names = &parent_name; + init.num_parents = 1; + + clock->reg = base + core->offset; + clock->hw.init = &init; + clock->div_table = cpg_sd_div_table; + clock->div_num = ARRAY_SIZE(cpg_sd_div_table); + + clock->div_max = clock->div_table[0].div; + clock->div_min = clock->div_max; + for (i = 1; i < clock->div_num; i++) { + clock->div_max = max(clock->div_max, clock->div_table[i].div); + clock->div_min = min(clock->div_min, clock->div_table[i].div); + } + + clk = clk_register(NULL, &clock->hw); + if (IS_ERR(clk)) + kfree(clock); + + return clk; +} + + +static const struct rcar_gen3_cpg_pll_config *cpg_pll_config __initdata; +static unsigned int cpg_clk_extalr __initdata; + +struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, + const struct cpg_core_clk *core, const struct cpg_mssr_info *info, + struct clk **clks, void __iomem *base) +{ + const struct clk *parent; + unsigned int mult = 1; + unsigned int div = 1; + u32 value; + + parent = clks[core->parent]; + if (IS_ERR(parent)) + return ERR_CAST(parent); + + switch (core->type) { + case CLK_TYPE_GEN3_MAIN: + div = cpg_pll_config->extal_div; + break; + + case CLK_TYPE_GEN3_PLL0: + /* + * PLL0 is a configurable multiplier clock. Register it as a + * fixed factor clock for now as there's no generic multiplier + * clock implementation and we currently have no need to change + * the multiplier value. + */ + value = readl(base + CPG_PLL0CR); + mult = (((value >> 24) & 0x7f) + 1) * 2; + break; + + case CLK_TYPE_GEN3_PLL1: + mult = cpg_pll_config->pll1_mult; + break; + + case CLK_TYPE_GEN3_PLL2: + /* + * PLL2 is a configurable multiplier clock. Register it as a + * fixed factor clock for now as there's no generic multiplier + * clock implementation and we currently have no need to change + * the multiplier value. + */ + value = readl(base + CPG_PLL2CR); + mult = (((value >> 24) & 0x7f) + 1) * 2; + break; + + case CLK_TYPE_GEN3_PLL3: + mult = cpg_pll_config->pll3_mult; + break; + + case CLK_TYPE_GEN3_PLL4: + /* + * PLL4 is a configurable multiplier clock. Register it as a + * fixed factor clock for now as there's no generic multiplier + * clock implementation and we currently have no need to change + * the multiplier value. + */ + value = readl(base + CPG_PLL4CR); + mult = (((value >> 24) & 0x7f) + 1) * 2; + break; + + case CLK_TYPE_GEN3_SD: + return cpg_sd_clk_register(core, base, __clk_get_name(parent)); + + case CLK_TYPE_GEN3_R: + /* + * RINT is default. + * Only if EXTALR is populated, we switch to it. + */ + value = readl(base + CPG_RCKCR) & 0x3f; + + if (clk_get_rate(clks[cpg_clk_extalr])) { + parent = clks[cpg_clk_extalr]; + value |= BIT(15); + } + + writel(value, base + CPG_RCKCR); + break; + + default: + return ERR_PTR(-EINVAL); + } + + return clk_register_fixed_factor(NULL, core->name, + __clk_get_name(parent), 0, mult, div); +} + +/* + * Reset register definitions. + */ +#define MODEMR 0xe6160060 + +u32 __init rcar_gen3_read_mode_pins(void) +{ + void __iomem *modemr = ioremap_nocache(MODEMR, 4); + u32 mode; + + BUG_ON(!modemr); + mode = ioread32(modemr); + iounmap(modemr); + + return mode; +} + +int __init rcar_gen3_cpg_init(const struct rcar_gen3_cpg_pll_config *config, + unsigned int clk_extalr) +{ + cpg_pll_config = config; + cpg_clk_extalr = clk_extalr; + return 0; +} diff --git a/drivers/clk/renesas/rcar-gen3-cpg.h b/drivers/clk/renesas/rcar-gen3-cpg.h new file mode 100644 index 000000000000..f699085147d1 --- /dev/null +++ b/drivers/clk/renesas/rcar-gen3-cpg.h @@ -0,0 +1,43 @@ +/* + * R-Car Gen3 Clock Pulse Generator + * + * Copyright (C) 2015-2016 Glider bvba + * + * 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. + */ + +#ifndef __CLK_RENESAS_RCAR_GEN3_CPG_H__ +#define __CLK_RENESAS_RCAR_GEN3_CPG_H__ + +enum rcar_gen3_clk_types { + CLK_TYPE_GEN3_MAIN = CLK_TYPE_CUSTOM, + CLK_TYPE_GEN3_PLL0, + CLK_TYPE_GEN3_PLL1, + CLK_TYPE_GEN3_PLL2, + CLK_TYPE_GEN3_PLL3, + CLK_TYPE_GEN3_PLL4, + CLK_TYPE_GEN3_SD, + CLK_TYPE_GEN3_R, +}; + +#define DEF_GEN3_SD(_name, _id, _parent, _offset) \ + DEF_BASE(_name, _id, CLK_TYPE_GEN3_SD, _parent, .offset = _offset) + +struct rcar_gen3_cpg_pll_config { + unsigned int extal_div; + unsigned int pll1_mult; + unsigned int pll3_mult; +}; + +#define CPG_RCKCR 0x240 + +u32 rcar_gen3_read_mode_pins(void); +struct clk *rcar_gen3_cpg_clk_register(struct device *dev, + const struct cpg_core_clk *core, const struct cpg_mssr_info *info, + struct clk **clks, void __iomem *base); +int rcar_gen3_cpg_init(const struct rcar_gen3_cpg_pll_config *config, + unsigned int clk_extalr); + +#endif From e4e2d7c388350eba8b1dbc2569441ac9b545a8c4 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 3 May 2016 11:06:15 +0200 Subject: [PATCH 04/19] clk: renesas: cpg-mssr: Add support for R-Car M3-W Initial support for R-Car M3-W (r8a7796), including basic core clocks, and SCIF2 (console) and INTC-AP (GIC) module clocks. Signed-off-by: Geert Uytterhoeven Tested-by: Simon Horman --- drivers/clk/renesas/Kconfig | 1 + drivers/clk/renesas/Makefile | 1 + drivers/clk/renesas/r8a7796-cpg-mssr.c | 192 +++++++++++++++++++++++++ drivers/clk/renesas/renesas-cpg-mssr.c | 6 + drivers/clk/renesas/renesas-cpg-mssr.h | 1 + 5 files changed, 201 insertions(+) create mode 100644 drivers/clk/renesas/r8a7796-cpg-mssr.c diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index 2115ce410cfb..fcad9ff090f5 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -1,6 +1,7 @@ config CLK_RENESAS_CPG_MSSR bool default y if ARCH_R8A7795 + default y if ARCH_R8A7796 config CLK_RENESAS_CPG_MSTP bool diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index 88924c95808c..0b8d31b4909c 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_ARCH_R8A7791) += clk-rcar-gen2.o clk-div6.o obj-$(CONFIG_ARCH_R8A7793) += clk-rcar-gen2.o clk-div6.o obj-$(CONFIG_ARCH_R8A7794) += clk-rcar-gen2.o clk-div6.o obj-$(CONFIG_ARCH_R8A7795) += r8a7795-cpg-mssr.o rcar-gen3-cpg.o +obj-$(CONFIG_ARCH_R8A7796) += r8a7796-cpg-mssr.o rcar-gen3-cpg.o obj-$(CONFIG_ARCH_SH73A0) += clk-sh73a0.o clk-div6.o obj-$(CONFIG_CLK_RENESAS_CPG_MSSR) += renesas-cpg-mssr.o clk-div6.o diff --git a/drivers/clk/renesas/r8a7796-cpg-mssr.c b/drivers/clk/renesas/r8a7796-cpg-mssr.c new file mode 100644 index 000000000000..c84b549c14d2 --- /dev/null +++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c @@ -0,0 +1,192 @@ +/* + * r8a7796 Clock Pulse Generator / Module Standby and Software Reset + * + * Copyright (C) 2016 Glider bvba + * + * Based on r8a7795-cpg-mssr.c + * + * Copyright (C) 2015 Glider bvba + * Copyright (C) 2015 Renesas Electronics Corp. + * + * 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. + */ + +#include +#include +#include + +#include + +#include "renesas-cpg-mssr.h" +#include "rcar-gen3-cpg.h" + +enum clk_ids { + /* Core Clock Outputs exported to DT */ + LAST_DT_CORE_CLK = R8A7796_CLK_OSC, + + /* External Input Clocks */ + CLK_EXTAL, + CLK_EXTALR, + + /* Internal Core Clocks */ + CLK_MAIN, + CLK_PLL0, + CLK_PLL1, + CLK_PLL2, + CLK_PLL3, + CLK_PLL4, + CLK_PLL1_DIV2, + CLK_PLL1_DIV4, + CLK_S0, + CLK_S1, + CLK_S2, + CLK_S3, + CLK_SDSRC, + CLK_SSPSRC, + + /* Module Clocks */ + MOD_CLK_BASE +}; + +static const struct cpg_core_clk r8a7796_core_clks[] __initconst = { + /* External Clock Inputs */ + DEF_INPUT("extal", CLK_EXTAL), + DEF_INPUT("extalr", CLK_EXTALR), + + /* Internal Core Clocks */ + DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN3_MAIN, CLK_EXTAL), + DEF_BASE(".pll0", CLK_PLL0, CLK_TYPE_GEN3_PLL0, CLK_MAIN), + DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN3_PLL1, CLK_MAIN), + DEF_BASE(".pll2", CLK_PLL2, CLK_TYPE_GEN3_PLL2, CLK_MAIN), + DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN3_PLL3, CLK_MAIN), + DEF_BASE(".pll4", CLK_PLL4, CLK_TYPE_GEN3_PLL4, CLK_MAIN), + + DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1), + DEF_FIXED(".pll1_div4", CLK_PLL1_DIV4, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED(".s0", CLK_S0, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED(".s1", CLK_S1, CLK_PLL1_DIV2, 3, 1), + DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1), + DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1), + + /* Core Clock Outputs */ + DEF_FIXED("ztr", R8A7796_CLK_ZTR, CLK_PLL1_DIV2, 6, 1), + DEF_FIXED("ztrd2", R8A7796_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1), + DEF_FIXED("zt", R8A7796_CLK_ZT, CLK_PLL1_DIV2, 4, 1), + DEF_FIXED("zx", R8A7796_CLK_ZX, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED("s0d1", R8A7796_CLK_S0D1, CLK_S0, 1, 1), + DEF_FIXED("s0d2", R8A7796_CLK_S0D2, CLK_S0, 2, 1), + DEF_FIXED("s0d3", R8A7796_CLK_S0D3, CLK_S0, 3, 1), + DEF_FIXED("s0d4", R8A7796_CLK_S0D4, CLK_S0, 4, 1), + DEF_FIXED("s0d6", R8A7796_CLK_S0D6, CLK_S0, 6, 1), + DEF_FIXED("s0d8", R8A7796_CLK_S0D8, CLK_S0, 8, 1), + DEF_FIXED("s0d12", R8A7796_CLK_S0D12, CLK_S0, 12, 1), + DEF_FIXED("s1d1", R8A7796_CLK_S1D1, CLK_S1, 1, 1), + DEF_FIXED("s1d2", R8A7796_CLK_S1D2, CLK_S1, 2, 1), + DEF_FIXED("s1d4", R8A7796_CLK_S1D4, CLK_S1, 4, 1), + DEF_FIXED("s2d1", R8A7796_CLK_S2D1, CLK_S2, 1, 1), + DEF_FIXED("s2d2", R8A7796_CLK_S2D2, CLK_S2, 2, 1), + DEF_FIXED("s2d4", R8A7796_CLK_S2D4, CLK_S2, 4, 1), + DEF_FIXED("s3d1", R8A7796_CLK_S3D1, CLK_S3, 1, 1), + DEF_FIXED("s3d2", R8A7796_CLK_S3D2, CLK_S3, 2, 1), + DEF_FIXED("s3d4", R8A7796_CLK_S3D4, CLK_S3, 4, 1), + + DEF_FIXED("cl", R8A7796_CLK_CL, CLK_PLL1_DIV2, 48, 1), + DEF_FIXED("cp", R8A7796_CLK_CP, CLK_EXTAL, 2, 1), +}; + +static const struct mssr_mod_clk r8a7796_mod_clks[] __initconst = { + DEF_MOD("scif2", 310, R8A7796_CLK_S3D4), + DEF_MOD("intc-ap", 408, R8A7796_CLK_S3D1), +}; + +static const unsigned int r8a7796_crit_mod_clks[] __initconst = { + MOD_CLK_ID(408), /* INTC-AP (GIC) */ +}; + + +/* + * CPG Clock Data + */ + +/* + * MD EXTAL PLL0 PLL1 PLL2 PLL3 PLL4 + * 14 13 19 17 (MHz) + *------------------------------------------------------------------- + * 0 0 0 0 16.66 x 1 x180 x192 x144 x192 x144 + * 0 0 0 1 16.66 x 1 x180 x192 x144 x128 x144 + * 0 0 1 0 Prohibited setting + * 0 0 1 1 16.66 x 1 x180 x192 x144 x192 x144 + * 0 1 0 0 20 x 1 x150 x160 x120 x160 x120 + * 0 1 0 1 20 x 1 x150 x160 x120 x106 x120 + * 0 1 1 0 Prohibited setting + * 0 1 1 1 20 x 1 x150 x160 x120 x160 x120 + * 1 0 0 0 25 x 1 x120 x128 x96 x128 x96 + * 1 0 0 1 25 x 1 x120 x128 x96 x84 x96 + * 1 0 1 0 Prohibited setting + * 1 0 1 1 25 x 1 x120 x128 x96 x128 x96 + * 1 1 0 0 33.33 / 2 x180 x192 x144 x192 x144 + * 1 1 0 1 33.33 / 2 x180 x192 x144 x128 x144 + * 1 1 1 0 Prohibited setting + * 1 1 1 1 33.33 / 2 x180 x192 x144 x192 x144 + */ +#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 11) | \ + (((md) & BIT(13)) >> 11) | \ + (((md) & BIT(19)) >> 18) | \ + (((md) & BIT(17)) >> 17)) + +static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] __initconst = { + /* EXTAL div PLL1 mult PLL3 mult */ + { 1, 192, 192, }, + { 1, 192, 128, }, + { 0, /* Prohibited setting */ }, + { 1, 192, 192, }, + { 1, 160, 160, }, + { 1, 160, 106, }, + { 0, /* Prohibited setting */ }, + { 1, 160, 160, }, + { 1, 128, 128, }, + { 1, 128, 84, }, + { 0, /* Prohibited setting */ }, + { 1, 128, 128, }, + { 2, 192, 192, }, + { 2, 192, 128, }, + { 0, /* Prohibited setting */ }, + { 2, 192, 192, }, +}; + +static int __init r8a7796_cpg_mssr_init(struct device *dev) +{ + const struct rcar_gen3_cpg_pll_config *cpg_pll_config; + u32 cpg_mode = rcar_gen3_read_mode_pins(); + + cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)]; + if (!cpg_pll_config->extal_div) { + dev_err(dev, "Prohibited setting (cpg_mode=0x%x)\n", cpg_mode); + return -EINVAL; + } + + return rcar_gen3_cpg_init(cpg_pll_config, CLK_EXTALR); +} + +const struct cpg_mssr_info r8a7796_cpg_mssr_info __initconst = { + /* Core Clocks */ + .core_clks = r8a7796_core_clks, + .num_core_clks = ARRAY_SIZE(r8a7796_core_clks), + .last_dt_core_clk = LAST_DT_CORE_CLK, + .num_total_core_clks = MOD_CLK_BASE, + + /* Module Clocks */ + .mod_clks = r8a7796_mod_clks, + .num_mod_clks = ARRAY_SIZE(r8a7796_mod_clks), + .num_hw_mod_clks = 12 * 32, + + /* Critical Module Clocks */ + .crit_mod_clks = r8a7796_crit_mod_clks, + .num_crit_mod_clks = ARRAY_SIZE(r8a7796_crit_mod_clks), + + /* Callbacks */ + .init = r8a7796_cpg_mssr_init, + .cpg_clk_register = rcar_gen3_cpg_clk_register, +}; diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index 210cd744a7a9..e1365e7491ae 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -508,6 +508,12 @@ static const struct of_device_id cpg_mssr_match[] = { .compatible = "renesas,r8a7795-cpg-mssr", .data = &r8a7795_cpg_mssr_info, }, +#endif +#ifdef CONFIG_ARCH_R8A7796 + { + .compatible = "renesas,r8a7796-cpg-mssr", + .data = &r8a7796_cpg_mssr_info, + }, #endif { /* sentinel */ } }; diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h index 0d1e3e811e79..ee7edfaf1408 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.h +++ b/drivers/clk/renesas/renesas-cpg-mssr.h @@ -131,4 +131,5 @@ struct cpg_mssr_info { }; extern const struct cpg_mssr_info r8a7795_cpg_mssr_info; +extern const struct cpg_mssr_info r8a7796_cpg_mssr_info; #endif From 13445de6e71ad219f8fce8736c45f57bb3b85571 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Fri, 3 Jun 2016 23:58:03 +0300 Subject: [PATCH 05/19] clk: renesas: rcar-gen2: Document R8A7792 support Renesas R8A7792 SoC is a member of the R-Car gen2 family and so has CPG... Signed-off-by: Sergei Shtylyov Acked-by: Simon Horman Acked-by: Rob Herring Signed-off-by: Geert Uytterhoeven --- .../devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt index 2a9a8edc8f35..f8c05bb4116e 100644 --- a/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt +++ b/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt @@ -10,6 +10,7 @@ Required Properties: - compatible: Must be one of - "renesas,r8a7790-cpg-clocks" for the r8a7790 CPG - "renesas,r8a7791-cpg-clocks" for the r8a7791 CPG + - "renesas,r8a7792-cpg-clocks" for the r8a7792 CPG - "renesas,r8a7793-cpg-clocks" for the r8a7793 CPG - "renesas,r8a7794-cpg-clocks" for the r8a7794 CPG and "renesas,rcar-gen2-cpg-clocks" as a fallback. From ef71b1eaa0e09a082027f15f9e040a6f636ce874 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Fri, 3 Jun 2016 23:59:07 +0300 Subject: [PATCH 06/19] clk: renesas: mstp: Document R8A7792 support Renesas R8A7792 SoC also has the CPG MSTP clocks... Signed-off-by: Sergei Shtylyov Acked-by: Simon Horman Acked-by: Rob Herring Signed-off-by: Geert Uytterhoeven --- .../devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt index 16ed18155160..da578ebdda28 100644 --- a/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt @@ -17,6 +17,7 @@ Required Properties: - "renesas,r8a7779-mstp-clocks" for R8A7779 (R-Car H1) MSTP gate clocks - "renesas,r8a7790-mstp-clocks" for R8A7790 (R-Car H2) MSTP gate clocks - "renesas,r8a7791-mstp-clocks" for R8A7791 (R-Car M2-W) MSTP gate clocks + - "renesas,r8a7792-mstp-clocks" for R8A7792 (R-Car V2H) MSTP gate clocks - "renesas,r8a7793-mstp-clocks" for R8A7793 (R-Car M2-N) MSTP gate clocks - "renesas,r8a7794-mstp-clocks" for R8A7794 (R-Car E2) MSTP gate clocks - "renesas,sh73a0-mstp-clocks" for SH73A0 (SH-MobileAG5) MSTP gate clocks From a233bffb6b5ad90a7e01a9c9b14b036d156eb0dd Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Thu, 26 May 2016 00:40:44 +0300 Subject: [PATCH 07/19] clk: renesas: Add R8A7792 support Renesas R-Car V2H (R8A7792) clocks are handled by R-Car gen2 clock driver. Signed-off-by: Sergei Shtylyov Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/Kconfig | 1 + drivers/clk/renesas/Makefile | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index fcad9ff090f5..41a12d376799 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -12,6 +12,7 @@ config CLK_RENESAS_CPG_MSTP default y if ARCH_R8A7779 default y if ARCH_R8A7790 default y if ARCH_R8A7791 + default y if ARCH_R8A7792 default y if ARCH_R8A7793 default y if ARCH_R8A7794 default y if ARCH_SH73A0 diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index 0b8d31b4909c..90dd0db7d9c6 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_ARCH_R8A7778) += clk-r8a7778.o obj-$(CONFIG_ARCH_R8A7779) += clk-r8a7779.o obj-$(CONFIG_ARCH_R8A7790) += clk-rcar-gen2.o clk-div6.o obj-$(CONFIG_ARCH_R8A7791) += clk-rcar-gen2.o clk-div6.o +obj-$(CONFIG_ARCH_R8A7792) += clk-rcar-gen2.o clk-div6.o obj-$(CONFIG_ARCH_R8A7793) += clk-rcar-gen2.o clk-div6.o obj-$(CONFIG_ARCH_R8A7794) += clk-rcar-gen2.o clk-div6.o obj-$(CONFIG_ARCH_R8A7795) += r8a7795-cpg-mssr.o rcar-gen3-cpg.o From a20956804220951196671ed5455d085927d6a754 Mon Sep 17 00:00:00 2001 From: Kieran Bingham Date: Thu, 9 Jun 2016 17:12:26 +0100 Subject: [PATCH 08/19] clk: renesas: r8a7795: Provide FDP1 clocks Reviewed-by: Laurent Pinchart Signed-off-by: Kieran Bingham Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r8a7795-cpg-mssr.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c index e53aff5b23ad..8f76af6f454d 100644 --- a/drivers/clk/renesas/r8a7795-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c @@ -107,6 +107,9 @@ static const struct cpg_core_clk r8a7795_core_clks[] __initconst = { }; static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = { + DEF_MOD("fdp1-2", 117, R8A7795_CLK_S2D1), + DEF_MOD("fdp1-1", 118, R8A7795_CLK_S2D1), + DEF_MOD("fdp1-0", 119, R8A7795_CLK_S2D1), DEF_MOD("scif5", 202, R8A7795_CLK_S3D4), DEF_MOD("scif4", 203, R8A7795_CLK_S3D4), DEF_MOD("scif3", 204, R8A7795_CLK_S3D4), From f7bb887fb898307dd575179303b710d933f242ea Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 10 Jun 2016 09:36:44 +0200 Subject: [PATCH 09/19] clk: renesas: r8a7795: Correct lvds clock parent According to the latest information, the parent clock of the LVDS module clock is the S0D4 clock, not the S2D1 clock. Note that this change has no influence on actual operation, as the rcar-du LVDS encoder driver doesn't use the parent clock's rate. Signed-off-by: Geert Uytterhoeven Reviewed-by: Laurent Pinchart --- drivers/clk/renesas/r8a7795-cpg-mssr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c index 8f76af6f454d..ad01b0b1bc5f 100644 --- a/drivers/clk/renesas/r8a7795-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c @@ -180,7 +180,7 @@ static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = { DEF_MOD("du2", 722, R8A7795_CLK_S2D1), DEF_MOD("du1", 723, R8A7795_CLK_S2D1), DEF_MOD("du0", 724, R8A7795_CLK_S2D1), - DEF_MOD("lvds", 727, R8A7795_CLK_S2D1), + DEF_MOD("lvds", 727, R8A7795_CLK_S0D4), DEF_MOD("hdmi1", 728, R8A7795_CLK_HDMI), DEF_MOD("hdmi0", 729, R8A7795_CLK_HDMI), DEF_MOD("vin7", 804, R8A7795_CLK_S2D1), From 7d6cc0cddbc2f1953b2ff6f5930a065e40b94507 Mon Sep 17 00:00:00 2001 From: Ramesh Shanmugasundaram Date: Fri, 17 Jun 2016 13:25:14 +0100 Subject: [PATCH 10/19] clk: renesas: r8a7795: Add DRIF clock This patch adds DRIF module clocks for r8a7795 SoC. Signed-off-by: Ramesh Shanmugasundaram Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r8a7795-cpg-mssr.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c index ad01b0b1bc5f..b9485ab891a0 100644 --- a/drivers/clk/renesas/r8a7795-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c @@ -138,6 +138,14 @@ static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = { DEF_MOD("intc-ap", 408, R8A7795_CLK_S3D1), DEF_MOD("audmac0", 502, R8A7795_CLK_S3D4), DEF_MOD("audmac1", 501, R8A7795_CLK_S3D4), + DEF_MOD("drif7", 508, R8A7795_CLK_S3D2), + DEF_MOD("drif6", 509, R8A7795_CLK_S3D2), + DEF_MOD("drif5", 510, R8A7795_CLK_S3D2), + DEF_MOD("drif4", 511, R8A7795_CLK_S3D2), + DEF_MOD("drif3", 512, R8A7795_CLK_S3D2), + DEF_MOD("drif2", 513, R8A7795_CLK_S3D2), + DEF_MOD("drif1", 514, R8A7795_CLK_S3D2), + DEF_MOD("drif0", 515, R8A7795_CLK_S3D2), DEF_MOD("hscif4", 516, R8A7795_CLK_S3D1), DEF_MOD("hscif3", 517, R8A7795_CLK_S3D1), DEF_MOD("hscif2", 518, R8A7795_CLK_S3D1), From e4c82863fd17bacb60080481c11eb0303d3f83d0 Mon Sep 17 00:00:00 2001 From: Khiem Nguyen Date: Sun, 19 Jun 2016 09:34:18 +0700 Subject: [PATCH 11/19] clk: renesas: r8a7795: Add THS/TSC clock Signed-off-by: Khiem Nguyen Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r8a7795-cpg-mssr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c index b9485ab891a0..d359c92e13a6 100644 --- a/drivers/clk/renesas/r8a7795-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c @@ -151,6 +151,7 @@ static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = { DEF_MOD("hscif2", 518, R8A7795_CLK_S3D1), DEF_MOD("hscif1", 519, R8A7795_CLK_S3D1), DEF_MOD("hscif0", 520, R8A7795_CLK_S3D1), + DEF_MOD("thermal", 522, R8A7795_CLK_CP), DEF_MOD("pwm", 523, R8A7795_CLK_S3D4), DEF_MOD("fcpvd3", 600, R8A7795_CLK_S2D1), DEF_MOD("fcpvd2", 601, R8A7795_CLK_S2D1), From a5547642a4e08c98edeaf4b62f6da0ac8ed2f6bd Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 10 Jun 2016 12:06:45 +0200 Subject: [PATCH 12/19] arm64: dts: r8a7795: Add missing blank lines between cpu nodes For consistency with a57_0/a57_1 cpu nodes, and all other nodes. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm64/boot/dts/renesas/r8a7795.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi index 04eb0bc65634..fad6dd8b7771 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi @@ -53,6 +53,7 @@ next-level-cache = <&L2_CA57>; enable-method = "psci"; }; + a57_2: cpu@2 { compatible = "arm,cortex-a57","arm,armv8"; reg = <0x2>; @@ -61,6 +62,7 @@ next-level-cache = <&L2_CA57>; enable-method = "psci"; }; + a57_3: cpu@3 { compatible = "arm,cortex-a57","arm,armv8"; reg = <0x3>; From 162cd7845d5e9e16663079cc589046b3e588c104 Mon Sep 17 00:00:00 2001 From: Ramesh Shanmugasundaram Date: Fri, 17 Jun 2016 13:35:43 +0100 Subject: [PATCH 13/19] arm64: dts: r8a7795: Add CAN FD support Adds CAN FD controller node for r8a7795. Note: CAN FD controller register base address specified in R-Car Gen3 Hardware User Manual v0.5E is incorrect. The correct address is: CAN FD - 0xe66c0000 Signed-off-by: Ramesh Shanmugasundaram Signed-off-by: Simon Horman --- arch/arm64/boot/dts/renesas/r8a7795.dtsi | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi index fad6dd8b7771..b902356873c2 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi @@ -583,6 +583,30 @@ status = "disabled"; }; + canfd: can@e66c0000 { + compatible = "renesas,r8a7795-canfd", + "renesas,rcar-gen3-canfd"; + reg = <0 0xe66c0000 0 0x8000>; + interrupts = , + ; + clocks = <&cpg CPG_MOD 914>, + <&cpg CPG_CORE R8A7795_CLK_CANFD>, + <&can_clk>; + clock-names = "fck", "canfd", "can_clk"; + assigned-clocks = <&cpg CPG_CORE R8A7795_CLK_CANFD>; + assigned-clock-rates = <40000000>; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + status = "disabled"; + + channel0 { + status = "disabled"; + }; + + channel1 { + status = "disabled"; + }; + }; + hscif0: serial@e6540000 { compatible = "renesas,hscif-r8a7795", "renesas,rcar-gen3-hscif", From 1561f20760ec96db4d6808b09f3a691edc22f937 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Tue, 24 May 2016 10:54:38 +0900 Subject: [PATCH 14/19] arm64: dts: r8a7796: Add Renesas R8A7796 SoC support Basic support for the Gen 3 R-Car M3-W SoC. Based on work for the r8a7795 and r8a7796 SoCs by Takeshi Kihara, Dirk Behme and Geert Uytterhoeven. Signed-off-by: Simon Horman Reviewed-by: Geert Uytterhoeven --- .../devicetree/bindings/arm/shmobile.txt | 4 + arch/arm64/Kconfig.platforms | 6 + arch/arm64/boot/dts/renesas/r8a7796.dtsi | 120 ++++++++++++++++++ 3 files changed, 130 insertions(+) create mode 100644 arch/arm64/boot/dts/renesas/r8a7796.dtsi diff --git a/Documentation/devicetree/bindings/arm/shmobile.txt b/Documentation/devicetree/bindings/arm/shmobile.txt index 9cf67e48f222..d5ed554830d7 100644 --- a/Documentation/devicetree/bindings/arm/shmobile.txt +++ b/Documentation/devicetree/bindings/arm/shmobile.txt @@ -29,6 +29,8 @@ SoCs: compatible = "renesas,r8a7794" - R-Car H3 (R8A77950) compatible = "renesas,r8a7795" + - R-Car M3-W (R8A77960) + compatible = "renesas,r8a7796" Boards: @@ -61,5 +63,7 @@ Boards: compatible = "renesas,porter", "renesas,r8a7791" - Salvator-X (RTP0RC7795SIPB0010S) compatible = "renesas,salvator-x", "renesas,r8a7795"; + - Salvator-X + compatible = "renesas,salvator-x", "renesas,r8a7796"; - SILK (RTP0RC7794LCB00011S) compatible = "renesas,silk", "renesas,r8a7794" diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index 7ef1d05859ae..2182fd5c8153 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -121,6 +121,12 @@ config ARCH_R8A7795 help This enables support for the Renesas R-Car H3 SoC. +config ARCH_R8A7796 + bool "Renesas R-Car M3-W SoC Platform" + depends on ARCH_RENESAS + help + This enables support for the Renesas R-Car M3-W SoC. + config ARCH_STRATIX10 bool "Altera's Stratix 10 SoCFPGA Family" help diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi new file mode 100644 index 000000000000..178debf68318 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi @@ -0,0 +1,120 @@ +/* + * Device Tree Source for the r8a7796 SoC + * + * Copyright (C) 2016 Renesas Electronics 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. + */ + +#include +#include + +/ { + compatible = "renesas,r8a7796"; + #address-cells = <2>; + #size-cells = <2>; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + /* 1 core only at this point */ + a57_0: cpu@0 { + compatible = "arm,cortex-a57", "arm,armv8"; + reg = <0x0>; + device_type = "cpu"; + next-level-cache = <&L2_CA57>; + enable-method = "psci"; + }; + + L2_CA57: cache-controller@0 { + compatible = "cache"; + reg = <0>; + cache-unified; + cache-level = <2>; + }; + }; + + extal_clk: extal { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* This value must be overridden by the board */ + clock-frequency = <0>; + }; + + extalr_clk: extalr { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* This value must be overridden by the board */ + clock-frequency = <0>; + }; + + /* External SCIF clock - to be overridden by boards that provide it */ + scif_clk: scif { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <0>; + }; + + soc { + compatible = "simple-bus"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + gic: interrupt-controller@f1010000 { + compatible = "arm,gic-400"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + reg = <0x0 0xf1010000 0 0x1000>, + <0x0 0xf1020000 0 0x20000>, + <0x0 0xf1040000 0 0x20000>, + <0x0 0xf1060000 0 0x20000>; + interrupts = ; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = , + , + , + ; + }; + + cpg: clock-controller@e6150000 { + compatible = "renesas,r8a7796-cpg-mssr"; + reg = <0 0xe6150000 0 0x1000>; + clocks = <&extal_clk>, <&extalr_clk>; + clock-names = "extal", "extalr"; + #clock-cells = <2>; + #power-domain-cells = <0>; + }; + + scif2: serial@e6e88000 { + compatible = "renesas,scif-r8a7796", + "renesas,rcar-gen3-scif", "renesas,scif"; + reg = <0 0xe6e88000 0 64>; + interrupts = ; + clocks = <&cpg CPG_MOD 310>, + <&cpg CPG_CORE R8A7796_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + power-domains = <&cpg>; + status = "disabled"; + }; + }; +}; From 006e1db8f7beb4525639bb82f544e01cc41129a9 Mon Sep 17 00:00:00 2001 From: Takeshi Kihara Date: Tue, 24 May 2016 10:54:39 +0900 Subject: [PATCH 15/19] arm64: dts: salvator-x: add Salvator-X board on R8A7796 SoC This patch adds initial board support for R8A7796 Salvator-X. Signed-off-by: Takeshi Kihara Signed-off-by: Simon Horman Reviewed-by: Geert Uytterhoeven --- arch/arm64/boot/dts/renesas/Makefile | 1 + .../boot/dts/renesas/r8a7796-salvator-x.dts | 45 +++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 arch/arm64/boot/dts/renesas/r8a7796-salvator-x.dts diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile index 9ce1890a650e..17139f7003a6 100644 --- a/arch/arm64/boot/dts/renesas/Makefile +++ b/arch/arm64/boot/dts/renesas/Makefile @@ -1,4 +1,5 @@ dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-salvator-x.dtb +dtb-$(CONFIG_ARCH_R8A7796) += r8a7796-salvator-x.dtb always := $(dtb-y) clean-files := *.dtb diff --git a/arch/arm64/boot/dts/renesas/r8a7796-salvator-x.dts b/arch/arm64/boot/dts/renesas/r8a7796-salvator-x.dts new file mode 100644 index 000000000000..9c52613fb88c --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a7796-salvator-x.dts @@ -0,0 +1,45 @@ +/* + * Device Tree Source for the Salvator-X board + * + * Copyright (C) 2016 Renesas Electronics 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. + */ + +/dts-v1/; +#include "r8a7796.dtsi" + +/ { + model = "Renesas Salvator-X board based on r8a7796"; + compatible = "renesas,salvator-x", "renesas,r8a7796"; + + aliases { + serial0 = &scif2; + }; + + chosen { + bootargs = "ignore_loglevel"; + stdout-path = "serial0:115200n8"; + }; + + memory@48000000 { + device_type = "memory"; + /* first 128MB is reserved for secure area. */ + reg = <0x0 0x48000000 0x0 0x78000000>; + }; +}; + +&extal_clk { + clock-frequency = <16666666>; +}; + +&scif2 { + status = "okay"; +}; + +&scif_clk { + clock-frequency = <14745600>; + status = "okay"; +}; From 56aebae0003f8987cf1f07238ec9e6243fe88080 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 31 May 2016 11:08:44 +0200 Subject: [PATCH 16/19] arm64: dts: r8a7796: Add SYSC PM Domains Add a device node for the System Controller. Hook up the Cortex-A57 CPU core and L2 cache/SCU to their respective PM Domains. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm64/boot/dts/renesas/r8a7796.dtsi | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi index 178debf68318..85f0843ddd87 100644 --- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi @@ -10,6 +10,7 @@ #include #include +#include / { compatible = "renesas,r8a7796"; @@ -30,6 +31,7 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x0>; device_type = "cpu"; + power-domains = <&sysc R8A7796_PD_CA57_CPU0>; next-level-cache = <&L2_CA57>; enable-method = "psci"; }; @@ -37,6 +39,7 @@ L2_CA57: cache-controller@0 { compatible = "cache"; reg = <0>; + power-domains = <&sysc R8A7796_PD_CA57_SCU>; cache-unified; cache-level = <2>; }; @@ -104,6 +107,12 @@ #power-domain-cells = <0>; }; + sysc: system-controller@e6180000 { + compatible = "renesas,r8a7796-sysc"; + reg = <0 0xe6180000 0 0x0400>; + #power-domain-cells = <1>; + }; + scif2: serial@e6e88000 { compatible = "renesas,scif-r8a7796", "renesas,rcar-gen3-scif", "renesas,scif"; From a9003187a984ea835b5533165d97733303c5399e Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 31 May 2016 11:08:45 +0200 Subject: [PATCH 17/19] arm64: dts: r8a7796: Use SYSC "always-on" PM Domain Hook up all devices that are part of the CPG/MSSR Clock Domain to the SYSC "always-on" PM Domain, for a more consistent device-power-area description in DT. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm64/boot/dts/renesas/r8a7796.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi index 85f0843ddd87..fab61eddede3 100644 --- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi @@ -122,7 +122,7 @@ <&cpg CPG_CORE R8A7796_CLK_S3D1>, <&scif_clk>; clock-names = "fck", "brg_int", "scif_clk"; - power-domains = <&cpg>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; status = "disabled"; }; }; From c8ce8007e5c0678fe40e3e401f68ee0b9e74ee92 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 27 Jun 2016 19:50:46 +0200 Subject: [PATCH 18/19] arm64: dts: r8a7796: Add RWDT node Add a device node for the Watchdog Timer (WDT) controller on the Renesas R-Car M3-W (r8a7796) SoC. Signed-off-by: Geert Uytterhoeven Acked-by: Wolfram Sang Signed-off-by: Simon Horman --- arch/arm64/boot/dts/renesas/r8a7796.dtsi | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi index fab61eddede3..1edf82440d78 100644 --- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi @@ -98,6 +98,15 @@ (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>; }; + wdt0: watchdog@e6020000 { + compatible = "renesas,r8a7796-wdt", + "renesas,rcar-gen3-wdt"; + reg = <0 0xe6020000 0 0x0c>; + clocks = <&cpg CPG_MOD 402>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + status = "disabled"; + }; + cpg: clock-controller@e6150000 { compatible = "renesas,r8a7796-cpg-mssr"; reg = <0 0xe6150000 0 0x1000>; From c805f1a7013a76ae63c002e52cc667d7c37228ea Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 27 Jun 2016 19:50:47 +0200 Subject: [PATCH 19/19] arm64: dts: r8a7796/salvator-x: Enable watchdog timer Enable the Watchdog Timer (WDT) controller on the Renesas Salvator-X board equipped with an R-Car M3-W (r8a7796) SoC. Signed-off-by: Geert Uytterhoeven Acked-by: Wolfram Sang Signed-off-by: Simon Horman --- arch/arm64/boot/dts/renesas/r8a7796-salvator-x.dts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r8a7796-salvator-x.dts b/arch/arm64/boot/dts/renesas/r8a7796-salvator-x.dts index 9c52613fb88c..e72be3856d79 100644 --- a/arch/arm64/boot/dts/renesas/r8a7796-salvator-x.dts +++ b/arch/arm64/boot/dts/renesas/r8a7796-salvator-x.dts @@ -43,3 +43,8 @@ clock-frequency = <14745600>; status = "okay"; }; + +&wdt0 { + timeout-sec = <60>; + status = "okay"; +};