From 2ebedd8d5ca8747fc7efd8a97129802bc6965468 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 21 Jun 2017 22:02:33 +0200 Subject: [PATCH 01/11] clk: renesas: div6: Document fields used for parent selection Add the missing documentation for the fields in struct div6_clock related to parent selection for DIV6 clocks with selectable parents, as found in R/SH-Mobile SoCs. Fixes: c6d67fb037f4eaaf ("clk: shmobile: div6: support selectable-input clocks") Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/clk-div6.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/clk/renesas/clk-div6.c b/drivers/clk/renesas/clk-div6.c index 0627860233cb..3e0040c0ac87 100644 --- a/drivers/clk/renesas/clk-div6.c +++ b/drivers/clk/renesas/clk-div6.c @@ -29,6 +29,9 @@ * @hw: handle between common and hardware-specific interfaces * @reg: IO-remapped register * @div: divisor value (1-64) + * @src_shift: Shift to access the register bits to select the parent clock + * @src_width: Number of register bits to select the parent clock (may be 0) + * @parents: Array to map from valid parent clocks indices to hardware indices */ struct div6_clock { struct clk_hw hw; From f83fbfddd8f65ddadc0dd2b0dd7f3097d42d8def Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 5 Jul 2017 13:41:00 +0200 Subject: [PATCH 02/11] clk: renesas: r8a7792: Add IMR-LX3/LSX3 clocks Add the module clocks for the Image Renderer Light (SRAM) Extended 3 (IMR-LX3/LSX3) Distortion Correction Engines on R-Car V2H. Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r8a7792-cpg-mssr.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/clk/renesas/r8a7792-cpg-mssr.c b/drivers/clk/renesas/r8a7792-cpg-mssr.c index a832b9b6f7b0..7f85bbf20bf7 100644 --- a/drivers/clk/renesas/r8a7792-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7792-cpg-mssr.c @@ -118,6 +118,13 @@ static const struct mssr_mod_clk r8a7792_mod_clks[] __initconst = { DEF_MOD("vin1", 810, R8A7792_CLK_ZG), DEF_MOD("vin0", 811, R8A7792_CLK_ZG), DEF_MOD("etheravb", 812, R8A7792_CLK_HP), + DEF_MOD("imr-lx3", 821, R8A7792_CLK_ZG), + DEF_MOD("imr-lsx3-1", 822, R8A7792_CLK_ZG), + DEF_MOD("imr-lsx3-0", 823, R8A7792_CLK_ZG), + DEF_MOD("imr-lsx3-5", 825, R8A7792_CLK_ZG), + DEF_MOD("imr-lsx3-4", 826, R8A7792_CLK_ZG), + DEF_MOD("imr-lsx3-3", 827, R8A7792_CLK_ZG), + DEF_MOD("imr-lsx3-2", 828, R8A7792_CLK_ZG), DEF_MOD("gyro-adc", 901, R8A7792_CLK_P), DEF_MOD("gpio7", 904, R8A7792_CLK_CP), DEF_MOD("gpio6", 905, R8A7792_CLK_CP), From 371dd373c6edd557a7cfdfe10207b498ae10a014 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 17 May 2017 17:25:47 +0200 Subject: [PATCH 03/11] clk: renesas: Allow compile-testing of all (sub)drivers Enable compile-testing of the remaining clock drivers and subdrivers, now dummies are available for of_clk_get_from_provider(), of_device_compatible_match(), and rcar_rst_read_mode_pins(), and the CPG/MSSR driver core has been converted from of_match_node() to of_device_get_match_data(). Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/Kconfig | 38 ++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index 78d1df9112ba..85526ca39202 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -34,94 +34,94 @@ config CLK_EMEV2 bool "Emma Mobile EV2 clock support" if COMPILE_TEST config CLK_RZA1 - bool + bool "RZ/A1H clock support" if COMPILE_TEST select CLK_RENESAS_CPG_MSTP config CLK_R8A73A4 - bool + bool "R-Mobile APE6 clock support" if COMPILE_TEST select CLK_RENESAS_CPG_MSTP select CLK_RENESAS_DIV6 config CLK_R8A7740 - bool + bool "R-Mobile A1 clock support" if COMPILE_TEST select CLK_RENESAS_CPG_MSTP select CLK_RENESAS_DIV6 config CLK_R8A7743 - bool + bool "RZ/G1M clock support" if COMPILE_TEST select CLK_RCAR_GEN2_CPG config CLK_R8A7745 - bool + bool "RZ/G1E clock support" if COMPILE_TEST select CLK_RCAR_GEN2_CPG config CLK_R8A7778 - bool + bool "R-Car M1A clock support" if COMPILE_TEST select CLK_RENESAS_CPG_MSTP config CLK_R8A7779 - bool + bool "R-Car H1 clock support" if COMPILE_TEST select CLK_RENESAS_CPG_MSTP config CLK_R8A7790 - bool + bool "R-Car H2 clock support" if COMPILE_TEST select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY select CLK_RCAR_GEN2_CPG select CLK_RENESAS_DIV6 config CLK_R8A7791 - bool + bool "R-Car M2-W/N clock support" if COMPILE_TEST select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY select CLK_RCAR_GEN2_CPG select CLK_RENESAS_DIV6 config CLK_R8A7792 - bool + bool "R-Car V2H clock support" if COMPILE_TEST select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY select CLK_RCAR_GEN2_CPG config CLK_R8A7794 - bool + bool "R-Car E2 clock support" if COMPILE_TEST select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY select CLK_RCAR_GEN2_CPG select CLK_RENESAS_DIV6 config CLK_R8A7795 - bool + bool "R-Car H3 clock support" if COMPILE_TEST select CLK_RCAR_GEN3_CPG config CLK_R8A7796 - bool + bool "R-Car M3-W clock support" if COMPILE_TEST select CLK_RCAR_GEN3_CPG config CLK_SH73A0 - bool + bool "SH-Mobile AG5 clock support" if COMPILE_TEST select CLK_RENESAS_CPG_MSTP select CLK_RENESAS_DIV6 # Family config CLK_RCAR_GEN2 - bool + bool "R-Car Gen2 legacy clock support" if COMPILE_TEST select CLK_RENESAS_CPG_MSTP select CLK_RENESAS_DIV6 config CLK_RCAR_GEN2_CPG - bool + bool "R-Car Gen2 CPG clock support" if COMPILE_TEST select CLK_RENESAS_CPG_MSSR config CLK_RCAR_GEN3_CPG - bool + bool "R-Car Gen3 CPG clock support" if COMPILE_TEST select CLK_RENESAS_CPG_MSSR # Generic config CLK_RENESAS_CPG_MSSR - bool + bool "CPG/MSSR clock support" if COMPILE_TEST select CLK_RENESAS_DIV6 config CLK_RENESAS_CPG_MSTP - bool + bool "MSTP clock support" if COMPILE_TEST config CLK_RENESAS_DIV6 bool "DIV6 clock support" if COMPILE_TEST From f317880c5b2bd9c2f3abcd1f799b17b922ac944f Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Tue, 18 Jul 2017 18:44:06 +0200 Subject: [PATCH 04/11] clk: renesas: rcar-gen3-cpg: Drop superfluous variable 'rate' is not used, so we can use 'parent_rate' directly. Signed-off-by: Wolfram Sang Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/rcar-gen3-cpg.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c index 3dee900522b7..71b8a986bd48 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.c +++ b/drivers/clk/renesas/rcar-gen3-cpg.c @@ -135,7 +135,6 @@ 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; @@ -149,7 +148,7 @@ static unsigned long cpg_sd_clock_recalc_rate(struct clk_hw *hw, if (i >= clock->div_num) return -EINVAL; - return DIV_ROUND_CLOSEST(rate, clock->div_table[i].div); + return DIV_ROUND_CLOSEST(parent_rate, clock->div_table[i].div); } static unsigned int cpg_sd_clock_calc_div(struct sd_clock *clock, From 2d6f25774332ebf6a0283d5bc558b273991797db Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Tue, 18 Jul 2017 18:44:07 +0200 Subject: [PATCH 05/11] clk: renesas: rcar-gen3-cpg: Refactor checks for accessing the div table Do the checks for accessing the SD divider table only when the rate gets updated, namely on init and set_rate. In all other cases, reuse the last value. This simplifies code, runtime load, and error reporting. Signed-off-by: Wolfram Sang Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/rcar-gen3-cpg.c | 46 +++++++++++++---------------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c index 71b8a986bd48..d4d27cf6110d 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.c +++ b/drivers/clk/renesas/rcar-gen3-cpg.c @@ -60,6 +60,7 @@ struct sd_clock { unsigned int div_num; unsigned int div_min; unsigned int div_max; + unsigned int cur_div_idx; }; /* SDn divider @@ -96,21 +97,10 @@ static const struct sd_div_table cpg_sd_div_table[] = { 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 = 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; + u32 val = readl(clock->reg); val &= ~(CPG_SD_STP_MASK); - val |= clock->div_table[i].val & CPG_SD_STP_MASK; + val |= clock->div_table[clock->cur_div_idx].val & CPG_SD_STP_MASK; writel(val, clock->reg); @@ -135,20 +125,9 @@ static unsigned long cpg_sd_clock_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct sd_clock *clock = to_sd_clock(hw); - u32 val, sd_fc; - unsigned int i; - val = 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(parent_rate, clock->div_table[i].div); + return DIV_ROUND_CLOSEST(parent_rate, + clock->div_table[clock->cur_div_idx].div); } static unsigned int cpg_sd_clock_calc_div(struct sd_clock *clock, @@ -189,6 +168,8 @@ static int cpg_sd_clock_set_rate(struct clk_hw *hw, unsigned long rate, if (i >= clock->div_num) return -EINVAL; + clock->cur_div_idx = i; + val = 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); @@ -214,6 +195,7 @@ static struct clk * __init cpg_sd_clk_register(const struct cpg_core_clk *core, struct sd_clock *clock; struct clk *clk; unsigned int i; + u32 sd_fc; clock = kzalloc(sizeof(*clock), GFP_KERNEL); if (!clock) @@ -230,6 +212,18 @@ static struct clk * __init cpg_sd_clk_register(const struct cpg_core_clk *core, clock->div_table = cpg_sd_div_table; clock->div_num = ARRAY_SIZE(cpg_sd_div_table); + sd_fc = readl(clock->reg) & 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 (WARN_ON(i >= clock->div_num)) { + kfree(clock); + return ERR_PTR(-EINVAL); + } + + clock->cur_div_idx = i; + clock->div_max = clock->div_table[0].div; clock->div_min = clock->div_max; for (i = 1; i < clock->div_num; i++) { From 714c53aa2e2d6d60ca1e7d18980767c8b715c288 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 11 Jul 2017 16:58:42 +0200 Subject: [PATCH 06/11] clk: renesas: Add r8a77995 CPG Core Clock Definitions Add all R-Car D3 Clock Pulse Generator Core Clock Outputs, as listed in Table 8.2f ("List of Clocks [R-Car D3]") of the R-Car Series, 3rd Generation Hardware User's Manual (Rev. 0.55, Jun. 30, 2017). Note that internal CPG clocks (S0, S1, S2, S3, S1C, S3C, 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 Acked-by: Stephen Boyd --- include/dt-bindings/clock/r8a77995-cpg-mssr.h | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 include/dt-bindings/clock/r8a77995-cpg-mssr.h diff --git a/include/dt-bindings/clock/r8a77995-cpg-mssr.h b/include/dt-bindings/clock/r8a77995-cpg-mssr.h new file mode 100644 index 000000000000..4e8ae3dee590 --- /dev/null +++ b/include/dt-bindings/clock/r8a77995-cpg-mssr.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2017 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; either version 2 of the License, or + * (at your option) any later version. + */ +#ifndef __DT_BINDINGS_CLOCK_R8A77995_CPG_MSSR_H__ +#define __DT_BINDINGS_CLOCK_R8A77995_CPG_MSSR_H__ + +#include + +/* r8a77995 CPG Core Clocks */ +#define R8A77995_CLK_Z2 0 +#define R8A77995_CLK_ZG 1 +#define R8A77995_CLK_ZTR 2 +#define R8A77995_CLK_ZT 3 +#define R8A77995_CLK_ZX 4 +#define R8A77995_CLK_S0D1 5 +#define R8A77995_CLK_S1D1 6 +#define R8A77995_CLK_S1D2 7 +#define R8A77995_CLK_S1D4 8 +#define R8A77995_CLK_S2D1 9 +#define R8A77995_CLK_S2D2 10 +#define R8A77995_CLK_S2D4 11 +#define R8A77995_CLK_S3D1 12 +#define R8A77995_CLK_S3D2 13 +#define R8A77995_CLK_S3D4 14 +#define R8A77995_CLK_S1D4C 15 +#define R8A77995_CLK_S3D1C 16 +#define R8A77995_CLK_S3D2C 17 +#define R8A77995_CLK_S3D4C 18 +#define R8A77995_CLK_LB 19 +#define R8A77995_CLK_CL 20 +#define R8A77995_CLK_ZB3 21 +#define R8A77995_CLK_ZB3D2 22 +#define R8A77995_CLK_CR 23 +#define R8A77995_CLK_CRD2 24 +#define R8A77995_CLK_SD0H 25 +#define R8A77995_CLK_SD0 26 +#define R8A77995_CLK_SSP2 27 +#define R8A77995_CLK_SSP1 28 +#define R8A77995_CLK_RPC 29 +#define R8A77995_CLK_RPCD2 30 +#define R8A77995_CLK_ZA2 31 +#define R8A77995_CLK_ZA8 32 +#define R8A77995_CLK_Z2D 33 +#define R8A77995_CLK_CANFD 34 +#define R8A77995_CLK_MSO 35 +#define R8A77995_CLK_R 36 +#define R8A77995_CLK_OSC 37 +#define R8A77995_CLK_LV0 38 +#define R8A77995_CLK_LV1 39 +#define R8A77995_CLK_CP 40 + +#endif /* __DT_BINDINGS_CLOCK_R8A77995_CPG_MSSR_H__ */ From 09a7dea9d58aadda90af5ad4dce1d540fe830868 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 19 Jul 2017 16:30:45 +0200 Subject: [PATCH 07/11] clk: renesas: rcar-gen3: Add divider support for PLL1 and PLL3 On some R-Car Gen3 SoCs (e.g. R-Car D3), PLL1 and PLL3 use a divider value different from one. Extend struct rcar_gen3_cpg_pll_config to handle this. As all multipliers and dividers are small, table size increase can be kept limited by storing them in u8s instead of unsigned ints, which saves ca. 0.5 KiB for a generic kernel. Signed-off-by: Geert Uytterhoeven Acked-by: Stephen Boyd --- drivers/clk/renesas/r8a7795-cpg-mssr.c | 34 +++++++++++++------------- drivers/clk/renesas/r8a7796-cpg-mssr.c | 34 +++++++++++++------------- drivers/clk/renesas/rcar-gen3-cpg.c | 2 ++ drivers/clk/renesas/rcar-gen3-cpg.h | 8 +++--- 4 files changed, 41 insertions(+), 37 deletions(-) diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c index c091a8e024b8..762b2f8824f1 100644 --- a/drivers/clk/renesas/r8a7795-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c @@ -305,23 +305,23 @@ static const unsigned int r8a7795_crit_mod_clks[] __initconst = { (((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, }, + /* EXTAL div PLL1 mult/div PLL3 mult/div */ + { 1, 192, 1, 192, 1, }, + { 1, 192, 1, 128, 1, }, + { 0, /* Prohibited setting */ }, + { 1, 192, 1, 192, 1, }, + { 1, 160, 1, 160, 1, }, + { 1, 160, 1, 106, 1, }, + { 0, /* Prohibited setting */ }, + { 1, 160, 1, 160, 1, }, + { 1, 128, 1, 128, 1, }, + { 1, 128, 1, 84, 1, }, + { 0, /* Prohibited setting */ }, + { 1, 128, 1, 128, 1, }, + { 2, 192, 1, 192, 1, }, + { 2, 192, 1, 128, 1, }, + { 0, /* Prohibited setting */ }, + { 2, 192, 1, 192, 1, }, }; static const struct soc_device_attribute r8a7795es1[] __initconst = { diff --git a/drivers/clk/renesas/r8a7796-cpg-mssr.c b/drivers/clk/renesas/r8a7796-cpg-mssr.c index acc6d0f153e1..22ba3c497aba 100644 --- a/drivers/clk/renesas/r8a7796-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c @@ -277,23 +277,23 @@ static const unsigned int r8a7796_crit_mod_clks[] __initconst = { (((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, }, + /* EXTAL div PLL1 mult/div PLL3 mult/div */ + { 1, 192, 1, 192, 1, }, + { 1, 192, 1, 128, 1, }, + { 0, /* Prohibited setting */ }, + { 1, 192, 1, 192, 1, }, + { 1, 160, 1, 160, 1, }, + { 1, 160, 1, 106, 1, }, + { 0, /* Prohibited setting */ }, + { 1, 160, 1, 160, 1, }, + { 1, 128, 1, 128, 1, }, + { 1, 128, 1, 84, 1, }, + { 0, /* Prohibited setting */ }, + { 1, 128, 1, 128, 1, }, + { 2, 192, 1, 192, 1, }, + { 2, 192, 1, 128, 1, }, + { 0, /* Prohibited setting */ }, + { 2, 192, 1, 192, 1, }, }; static int __init r8a7796_cpg_mssr_init(struct device *dev) diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c index d4d27cf6110d..3f922fea9671 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.c +++ b/drivers/clk/renesas/rcar-gen3-cpg.c @@ -296,6 +296,7 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, case CLK_TYPE_GEN3_PLL1: mult = cpg_pll_config->pll1_mult; + div = cpg_pll_config->pll1_div; break; case CLK_TYPE_GEN3_PLL2: @@ -313,6 +314,7 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, case CLK_TYPE_GEN3_PLL3: mult = cpg_pll_config->pll3_mult; + div = cpg_pll_config->pll3_div; break; case CLK_TYPE_GEN3_PLL4: diff --git a/drivers/clk/renesas/rcar-gen3-cpg.h b/drivers/clk/renesas/rcar-gen3-cpg.h index 073be54b5d03..4eaf02955580 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.h +++ b/drivers/clk/renesas/rcar-gen3-cpg.h @@ -26,9 +26,11 @@ enum rcar_gen3_clk_types { 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; + u8 extal_div; + u8 pll1_mult; + u8 pll1_div; + u8 pll3_mult; + u8 pll3_div; }; #define CPG_RCKCR 0x240 From 696997e004d4179f462d2ebd3efeb12a7cec5ef7 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 19 Jul 2017 17:39:54 +0200 Subject: [PATCH 08/11] clk: renesas: rcar-gen3: Add support for SCCG/Clean peripheral clocks On R-Car Gen3 SoCs with a Spread Spectrum Clock Generator (e.g. R-Car D3), a peripheral clock divider has been added, to select between clean and spread spectrum parents. Add a new clock type to the R-Car Gen3 driver core to handle this. To avoid increasing the size of struct cpg_core_clk, both parents and dividers are stored in the existing parent resp. div fields. Signed-off-by: Geert Uytterhoeven Acked-by: Stephen Boyd --- drivers/clk/renesas/rcar-gen3-cpg.c | 20 +++++++++++++++++++- drivers/clk/renesas/rcar-gen3-cpg.h | 7 +++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c index 3f922fea9671..951105816547 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.c +++ b/drivers/clk/renesas/rcar-gen3-cpg.c @@ -272,7 +272,7 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, unsigned int div = 1; u32 value; - parent = clks[core->parent]; + parent = clks[core->parent & 0xffff]; /* CLK_TYPE_PE uses high bits */ if (IS_ERR(parent)) return ERR_CAST(parent); @@ -355,6 +355,24 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, parent = clks[cpg_clk_extalr]; break; + case CLK_TYPE_GEN3_PE: + /* + * Peripheral clock with a fixed divider, selectable between + * clean and spread spectrum parents using MD12 + */ + if (cpg_mode & BIT(12)) { + /* Clean */ + div = core->div & 0xffff; + } else { + /* SCCG */ + parent = clks[core->parent >> 16]; + if (IS_ERR(parent)) + return ERR_CAST(parent); + div = core->div >> 16; + } + mult = 1; + break; + default: return ERR_PTR(-EINVAL); } diff --git a/drivers/clk/renesas/rcar-gen3-cpg.h b/drivers/clk/renesas/rcar-gen3-cpg.h index 4eaf02955580..d756ef8b78eb 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.h +++ b/drivers/clk/renesas/rcar-gen3-cpg.h @@ -20,11 +20,18 @@ enum rcar_gen3_clk_types { CLK_TYPE_GEN3_PLL4, CLK_TYPE_GEN3_SD, CLK_TYPE_GEN3_R, + CLK_TYPE_GEN3_PE, }; #define DEF_GEN3_SD(_name, _id, _parent, _offset) \ DEF_BASE(_name, _id, CLK_TYPE_GEN3_SD, _parent, .offset = _offset) +#define DEF_GEN3_PE(_name, _id, _parent_sscg, _div_sscg, _parent_clean, \ + _div_clean) \ + DEF_BASE(_name, _id, CLK_TYPE_GEN3_PE, \ + (_parent_sscg) << 16 | (_parent_clean), \ + .div = (_div_sscg) << 16 | (_div_clean)) + struct rcar_gen3_cpg_pll_config { u8 extal_div; u8 pll1_mult; From d71e851d82c6cfe58bc592ce1e59e924f0374d0f Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 12 Jul 2017 10:47:36 +0200 Subject: [PATCH 09/11] clk: renesas: cpg-mssr: Add R8A77995 support Add R-Car D3 (R8A77995) Clock Pulse Generator / Module Standby and Software Reset support, using the CPG/MSSR driver core and the common R-Car Gen3 CPG code. Based on the R-Car Series, 3rd Generation Hardware User's Manual, Rev. 0.55, Jun. 30, 2017. Signed-off-by: Geert Uytterhoeven Acked-by: Stephen Boyd Acked-by: Rob Herring --- .../bindings/clock/renesas,cpg-mssr.txt | 3 +- drivers/clk/renesas/Kconfig | 5 + drivers/clk/renesas/Makefile | 1 + drivers/clk/renesas/r8a77995-cpg-mssr.c | 236 ++++++++++++++++++ drivers/clk/renesas/renesas-cpg-mssr.c | 6 + drivers/clk/renesas/renesas-cpg-mssr.h | 1 + 6 files changed, 251 insertions(+), 1 deletion(-) create mode 100644 drivers/clk/renesas/r8a77995-cpg-mssr.c diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt index 0cd894f987a3..27cec3258538 100644 --- a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt @@ -22,6 +22,7 @@ Required Properties: - "renesas,r8a7794-cpg-mssr" for the r8a7794 SoC (R-Car E2) - "renesas,r8a7795-cpg-mssr" for the r8a7795 SoC (R-Car H3) - "renesas,r8a7796-cpg-mssr" for the r8a7796 SoC (R-Car M3-W) + - "renesas,r8a77995-cpg-mssr" for the r8a77995 SoC (R-Car D3) - reg: Base address and length of the memory resource used by the CPG/MSSR block @@ -30,7 +31,7 @@ Required Properties: clock-names - clock-names: List of external parent clock names. Valid names are: - "extal" (r8a7743, r8a7745, r8a7790, r8a7791, r8a7792, r8a7793, r8a7794, - r8a7795, r8a7796) + r8a7795, r8a7796, r8a77995) - "extalr" (r8a7795, r8a7796) - "usb_extal" (r8a7743, r8a7745, r8a7790, r8a7791, r8a7793, r8a7794) diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index 85526ca39202..eee076deb739 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -15,6 +15,7 @@ config CLK_RENESAS select CLK_R8A7794 if ARCH_R8A7794 select CLK_R8A7795 if ARCH_R8A7795 select CLK_R8A7796 if ARCH_R8A7796 + select CLK_R8A77995 if ARCH_R8A77995 select CLK_SH73A0 if ARCH_SH73A0 if CLK_RENESAS @@ -94,6 +95,10 @@ config CLK_R8A7796 bool "R-Car M3-W clock support" if COMPILE_TEST select CLK_RCAR_GEN3_CPG +config CLK_R8A77995 + bool "R-Car D3 clock support" if COMPILE_TEST + select CLK_RCAR_GEN3_CPG + config CLK_SH73A0 bool "SH-Mobile AG5 clock support" if COMPILE_TEST select CLK_RENESAS_CPG_MSTP diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index 02d04124371f..a3bb1fadf1a6 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_CLK_R8A7792) += r8a7792-cpg-mssr.o obj-$(CONFIG_CLK_R8A7794) += r8a7794-cpg-mssr.o obj-$(CONFIG_CLK_R8A7795) += r8a7795-cpg-mssr.o obj-$(CONFIG_CLK_R8A7796) += r8a7796-cpg-mssr.o +obj-$(CONFIG_CLK_R8A77995) += r8a77995-cpg-mssr.o obj-$(CONFIG_CLK_SH73A0) += clk-sh73a0.o # Family diff --git a/drivers/clk/renesas/r8a77995-cpg-mssr.c b/drivers/clk/renesas/r8a77995-cpg-mssr.c new file mode 100644 index 000000000000..e594cf8ee63b --- /dev/null +++ b/drivers/clk/renesas/r8a77995-cpg-mssr.c @@ -0,0 +1,236 @@ +/* + * r8a77995 Clock Pulse Generator / Module Standby and Software Reset + * + * Copyright (C) 2017 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 + +#include "renesas-cpg-mssr.h" +#include "rcar-gen3-cpg.h" + +enum clk_ids { + /* Core Clock Outputs exported to DT */ + LAST_DT_CORE_CLK = R8A77995_CLK_CP, + + /* External Input Clocks */ + CLK_EXTAL, + + /* Internal Core Clocks */ + CLK_MAIN, + CLK_PLL0, + CLK_PLL1, + CLK_PLL3, + CLK_PLL0D2, + CLK_PLL0D3, + CLK_PLL0D5, + CLK_PLL1D2, + CLK_PE, + CLK_S0, + CLK_S1, + CLK_S2, + CLK_S3, + CLK_SDSRC, + CLK_SSPSRC, + + /* Module Clocks */ + MOD_CLK_BASE +}; + +static const struct cpg_core_clk r8a77995_core_clks[] __initconst = { + /* External Clock Inputs */ + DEF_INPUT("extal", CLK_EXTAL), + + /* Internal Core Clocks */ + DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN3_MAIN, CLK_EXTAL), + DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN3_PLL1, CLK_MAIN), + DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN3_PLL3, CLK_MAIN), + + DEF_FIXED(".pll0", CLK_PLL0, CLK_MAIN, 4, 250), + DEF_FIXED(".pll0d2", CLK_PLL0D2, CLK_PLL0, 2, 1), + DEF_FIXED(".pll0d3", CLK_PLL0D3, CLK_PLL0, 3, 1), + DEF_FIXED(".pll0d5", CLK_PLL0D5, CLK_PLL0, 5, 1), + DEF_FIXED(".pll1d2", CLK_PLL1D2, CLK_PLL1, 2, 1), + DEF_FIXED(".pe", CLK_PE, CLK_PLL0D3, 4, 1), + DEF_FIXED(".s0", CLK_S0, CLK_PLL1, 2, 1), + DEF_FIXED(".s1", CLK_S1, CLK_PLL1, 3, 1), + DEF_FIXED(".s2", CLK_S2, CLK_PLL1, 4, 1), + DEF_FIXED(".s3", CLK_S3, CLK_PLL1, 6, 1), + DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1, 2, 1), + + /* Core Clock Outputs */ + DEF_FIXED("z2", R8A77995_CLK_Z2, CLK_PLL0D3, 1, 1), + DEF_FIXED("ztr", R8A77995_CLK_ZTR, CLK_PLL1, 6, 1), + DEF_FIXED("zt", R8A77995_CLK_ZT, CLK_PLL1, 4, 1), + DEF_FIXED("zx", R8A77995_CLK_ZX, CLK_PLL1, 3, 1), + DEF_FIXED("s0d1", R8A77995_CLK_S0D1, CLK_S0, 1, 1), + DEF_FIXED("s1d1", R8A77995_CLK_S1D1, CLK_S1, 1, 1), + DEF_FIXED("s1d2", R8A77995_CLK_S1D2, CLK_S1, 2, 1), + DEF_FIXED("s1d4", R8A77995_CLK_S1D4, CLK_S1, 4, 1), + DEF_FIXED("s2d1", R8A77995_CLK_S2D1, CLK_S2, 1, 1), + DEF_FIXED("s2d2", R8A77995_CLK_S2D2, CLK_S2, 2, 1), + DEF_FIXED("s2d4", R8A77995_CLK_S2D4, CLK_S2, 4, 1), + DEF_FIXED("s3d1", R8A77995_CLK_S3D1, CLK_S3, 1, 1), + DEF_FIXED("s3d2", R8A77995_CLK_S3D2, CLK_S3, 2, 1), + DEF_FIXED("s3d4", R8A77995_CLK_S3D4, CLK_S3, 4, 1), + + DEF_FIXED("cl", R8A77995_CLK_CL, CLK_PLL1, 48, 1), + DEF_FIXED("cp", R8A77995_CLK_CP, CLK_EXTAL, 2, 1), + DEF_FIXED("osc", R8A77995_CLK_OSC, CLK_EXTAL, 384, 1), + DEF_FIXED("r", R8A77995_CLK_R, CLK_EXTAL, 1536, 1), + + DEF_GEN3_PE("s1d4c", R8A77995_CLK_S1D4C, CLK_S1, 4, CLK_PE, 2), + DEF_GEN3_PE("s3d1c", R8A77995_CLK_S3D1C, CLK_S3, 1, CLK_PE, 1), + DEF_GEN3_PE("s3d2c", R8A77995_CLK_S3D2C, CLK_S3, 2, CLK_PE, 2), + DEF_GEN3_PE("s3d4c", R8A77995_CLK_S3D4C, CLK_S3, 4, CLK_PE, 4), + + DEF_GEN3_SD("sd0", R8A77995_CLK_SD0, CLK_SDSRC, 0x268), + + DEF_DIV6P1("canfd", R8A77995_CLK_CANFD, CLK_PLL0D3, 0x244), + DEF_DIV6P1("mso", R8A77995_CLK_MSO, CLK_PLL1D2, 0x014), +}; + +static const struct mssr_mod_clk r8a77995_mod_clks[] __initconst = { + DEF_MOD("scif5", 202, R8A77995_CLK_S3D4C), + DEF_MOD("scif4", 203, R8A77995_CLK_S3D4C), + DEF_MOD("scif3", 204, R8A77995_CLK_S3D4C), + DEF_MOD("scif1", 206, R8A77995_CLK_S3D4C), + DEF_MOD("scif0", 207, R8A77995_CLK_S3D4C), + DEF_MOD("msiof3", 208, R8A77995_CLK_MSO), + DEF_MOD("msiof2", 209, R8A77995_CLK_MSO), + DEF_MOD("msiof1", 210, R8A77995_CLK_MSO), + DEF_MOD("msiof0", 211, R8A77995_CLK_MSO), + DEF_MOD("sys-dmac2", 217, R8A77995_CLK_S3D1), + DEF_MOD("sys-dmac1", 218, R8A77995_CLK_S3D1), + DEF_MOD("sys-dmac0", 219, R8A77995_CLK_S3D1), + DEF_MOD("cmt3", 300, R8A77995_CLK_R), + DEF_MOD("cmt2", 301, R8A77995_CLK_R), + DEF_MOD("cmt1", 302, R8A77995_CLK_R), + DEF_MOD("cmt0", 303, R8A77995_CLK_R), + DEF_MOD("scif2", 310, R8A77995_CLK_S3D4C), + DEF_MOD("emmc0", 312, R8A77995_CLK_SD0), + DEF_MOD("usb-dmac0", 330, R8A77995_CLK_S3D1), + DEF_MOD("usb-dmac1", 331, R8A77995_CLK_S3D1), + DEF_MOD("rwdt", 402, R8A77995_CLK_R), + DEF_MOD("intc-ex", 407, R8A77995_CLK_CP), + DEF_MOD("intc-ap", 408, R8A77995_CLK_S3D1), + DEF_MOD("audmac0", 502, R8A77995_CLK_S3D1), + DEF_MOD("hscif3", 517, R8A77995_CLK_S3D1C), + DEF_MOD("hscif0", 520, R8A77995_CLK_S3D1C), + DEF_MOD("thermal", 522, R8A77995_CLK_CP), + DEF_MOD("pwm", 523, R8A77995_CLK_S3D4C), + DEF_MOD("fcpvd1", 602, R8A77995_CLK_S1D2), + DEF_MOD("fcpvd0", 603, R8A77995_CLK_S1D2), + DEF_MOD("fcpvbs", 607, R8A77995_CLK_S0D1), + DEF_MOD("vspd1", 622, R8A77995_CLK_S1D2), + DEF_MOD("vspd0", 623, R8A77995_CLK_S1D2), + DEF_MOD("vspbs", 627, R8A77995_CLK_S0D1), + DEF_MOD("ehci0", 703, R8A77995_CLK_S3D2), + DEF_MOD("hsusb", 704, R8A77995_CLK_S3D2), + DEF_MOD("du1", 723, R8A77995_CLK_S2D1), + DEF_MOD("du0", 724, R8A77995_CLK_S2D1), + DEF_MOD("lvds", 727, R8A77995_CLK_S2D1), + DEF_MOD("vin7", 804, R8A77995_CLK_S1D2), + DEF_MOD("vin6", 805, R8A77995_CLK_S1D2), + DEF_MOD("vin5", 806, R8A77995_CLK_S1D2), + DEF_MOD("vin4", 807, R8A77995_CLK_S1D2), + DEF_MOD("etheravb", 812, R8A77995_CLK_S3D2), + DEF_MOD("imr0", 823, R8A77995_CLK_S1D2), + DEF_MOD("gpio6", 906, R8A77995_CLK_S3D4), + DEF_MOD("gpio5", 907, R8A77995_CLK_S3D4), + DEF_MOD("gpio4", 908, R8A77995_CLK_S3D4), + DEF_MOD("gpio3", 909, R8A77995_CLK_S3D4), + DEF_MOD("gpio2", 910, R8A77995_CLK_S3D4), + DEF_MOD("gpio1", 911, R8A77995_CLK_S3D4), + DEF_MOD("gpio0", 912, R8A77995_CLK_S3D4), + DEF_MOD("can-fd", 914, R8A77995_CLK_S3D2), + DEF_MOD("can-if1", 915, R8A77995_CLK_S3D4), + DEF_MOD("can-if0", 916, R8A77995_CLK_S3D4), + DEF_MOD("i2c3", 928, R8A77995_CLK_S3D2), + DEF_MOD("i2c2", 929, R8A77995_CLK_S3D2), + DEF_MOD("i2c1", 930, R8A77995_CLK_S3D2), + DEF_MOD("i2c0", 931, R8A77995_CLK_S3D2), + DEF_MOD("ssi-all", 1005, R8A77995_CLK_S3D4), + DEF_MOD("ssi4", 1011, MOD_CLK_ID(1005)), + DEF_MOD("ssi3", 1012, MOD_CLK_ID(1005)), + DEF_MOD("scu-all", 1017, R8A77995_CLK_S3D4), + DEF_MOD("scu-dvc1", 1018, MOD_CLK_ID(1017)), + DEF_MOD("scu-dvc0", 1019, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu1-mix1", 1020, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu0-mix0", 1021, MOD_CLK_ID(1017)), + DEF_MOD("scu-src6", 1025, MOD_CLK_ID(1017)), + DEF_MOD("scu-src5", 1026, MOD_CLK_ID(1017)), +}; + +static const unsigned int r8a77995_crit_mod_clks[] __initconst = { + MOD_CLK_ID(408), /* INTC-AP (GIC) */ +}; + + +/* + * CPG Clock Data + */ + +/* + * MD19 EXTAL (MHz) PLL0 PLL1 PLL3 + *-------------------------------------------------------------------- + * 0 48 x 1 x250/4 x100/3 x100/3 + * 1 48 x 1 x250/4 x100/3 x116/6 + */ +#define CPG_PLL_CONFIG_INDEX(md) (((md) & BIT(19)) >> 19) + +static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[2] __initconst = { + /* EXTAL div PLL1 mult/div PLL3 mult/div */ + { 1, 100, 3, 100, 3, }, + { 1, 100, 3, 116, 6, }, +}; + +static int __init r8a77995_cpg_mssr_init(struct device *dev) +{ + const struct rcar_gen3_cpg_pll_config *cpg_pll_config; + u32 cpg_mode; + int error; + + error = rcar_rst_read_mode_pins(&cpg_mode); + if (error) + return error; + + cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)]; + + return rcar_gen3_cpg_init(cpg_pll_config, 0, cpg_mode); +} + +const struct cpg_mssr_info r8a77995_cpg_mssr_info __initconst = { + /* Core Clocks */ + .core_clks = r8a77995_core_clks, + .num_core_clks = ARRAY_SIZE(r8a77995_core_clks), + .last_dt_core_clk = LAST_DT_CORE_CLK, + .num_total_core_clks = MOD_CLK_BASE, + + /* Module Clocks */ + .mod_clks = r8a77995_mod_clks, + .num_mod_clks = ARRAY_SIZE(r8a77995_mod_clks), + .num_hw_mod_clks = 12 * 32, + + /* Critical Module Clocks */ + .crit_mod_clks = r8a77995_crit_mod_clks, + .num_crit_mod_clks = ARRAY_SIZE(r8a77995_crit_mod_clks), + + /* Callbacks */ + .init = r8a77995_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 1f607c806f9b..e580a5e6346c 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -679,6 +679,12 @@ static const struct of_device_id cpg_mssr_match[] = { .compatible = "renesas,r8a7796-cpg-mssr", .data = &r8a7796_cpg_mssr_info, }, +#endif +#ifdef CONFIG_CLK_R8A77995 + { + .compatible = "renesas,r8a77995-cpg-mssr", + .data = &r8a77995_cpg_mssr_info, + }, #endif { /* sentinel */ } }; diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h index 43d7c7f6832d..94b9071d1061 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.h +++ b/drivers/clk/renesas/renesas-cpg-mssr.h @@ -138,6 +138,7 @@ extern const struct cpg_mssr_info r8a7792_cpg_mssr_info; extern const struct cpg_mssr_info r8a7794_cpg_mssr_info; extern const struct cpg_mssr_info r8a7795_cpg_mssr_info; extern const struct cpg_mssr_info r8a7796_cpg_mssr_info; +extern const struct cpg_mssr_info r8a77995_cpg_mssr_info; /* From 311accb64570db45604dd8929af6f7da735835c9 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Tue, 25 Jul 2017 15:26:27 +0900 Subject: [PATCH 10/11] clk: renesas: rcar-usb2-clock-sel: Add R-Car USB 2.0 clock selector PHY R-Car USB 2.0 controller can change the clock source from an oscillator to an external clock via a register. So, this patch adds support the clock source selector as a clock driver. Signed-off-by: Yoshihiro Shimoda Acked-by: Rob Herring Signed-off-by: Geert Uytterhoeven --- .../clock/renesas,rcar-usb2-clock-sel.txt | 55 +++++ drivers/clk/renesas/Kconfig | 5 + drivers/clk/renesas/Makefile | 1 + drivers/clk/renesas/rcar-usb2-clock-sel.c | 188 ++++++++++++++++++ 4 files changed, 249 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.txt create mode 100644 drivers/clk/renesas/rcar-usb2-clock-sel.c diff --git a/Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.txt b/Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.txt new file mode 100644 index 000000000000..e96e085271c1 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.txt @@ -0,0 +1,55 @@ +* Renesas R-Car USB 2.0 clock selector + +This file provides information on what the device node for the R-Car USB 2.0 +clock selector. + +If you connect an external clock to the USB_EXTAL pin only, you should set +the clock rate to "usb_extal" node only. +If you connect an oscillator to both the USB_XTAL and USB_EXTAL, this module +is not needed because this is default setting. (Of course, you can set the +clock rates to both "usb_extal" and "usb_xtal" nodes. + +Case 1: An external clock connects to R-Car SoC + +----------+ +--- R-Car ---------------------+ + |External |---|USB_EXTAL ---> all usb channels| + |clock | |USB_XTAL | + +----------+ +-------------------------------+ +In this case, we need this driver with "usb_extal" clock. + +Case 2: An oscillator connects to R-Car SoC + +----------+ +--- R-Car ---------------------+ + |Oscillator|---|USB_EXTAL -+-> all usb channels| + | |---|USB_XTAL --+ | + +----------+ +-------------------------------+ +In this case, we don't need this selector. + +Required properties: +- compatible: "renesas,r8a7795-rcar-usb2-clock-sel" if the device is a part of + an R8A7795 SoC. + "renesas,r8a7796-rcar-usb2-clock-sel" if the device if a part of + an R8A7796 SoC. + "renesas,rcar-gen3-usb2-clock-sel" for a generic R-Car Gen3 + compatible device. + + When compatible with the generic version, nodes must list the + SoC-specific version corresponding to the platform first + followed by the generic version. + +- reg: offset and length of the USB 2.0 clock selector register block. +- clocks: A list of phandles and specifier pairs. +- clock-names: Name of the clocks. + - The functional clock must be "ehci_ohci" + - The USB_EXTAL clock pin must be "usb_extal" + - The USB_XTAL clock pin must be "usb_xtal" +- #clock-cells: Must be 0 + +Example (R-Car H3): + + usb2_clksel: clock-controller@e6590630 { + compatible = "renesas,r8a77950-rcar-usb2-clock-sel", + "renesas,rcar-gen3-usb2-clock-sel"; + reg = <0 0xe6590630 0 0x02>; + clocks = <&cpg CPG_MOD 703>, <&usb_extal>, <&usb_xtal>; + clock-names = "ehci_ohci", "usb_extal", "usb_xtal"; + #clock-cells = <0>; + }; diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index eee076deb739..acbb38151ba1 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -119,6 +119,11 @@ config CLK_RCAR_GEN3_CPG bool "R-Car Gen3 CPG clock support" if COMPILE_TEST select CLK_RENESAS_CPG_MSSR +config CLK_RCAR_USB2_CLOCK_SEL + bool "Renesas R-Car USB2 clock selector support" + depends on ARCH_RENESAS || COMPILE_TEST + help + This is a driver for R-Car USB2 clock selector # Generic config CLK_RENESAS_CPG_MSSR diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index a3bb1fadf1a6..9bda3ec5b199 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_CLK_SH73A0) += clk-sh73a0.o obj-$(CONFIG_CLK_RCAR_GEN2) += clk-rcar-gen2.o obj-$(CONFIG_CLK_RCAR_GEN2_CPG) += rcar-gen2-cpg.o obj-$(CONFIG_CLK_RCAR_GEN3_CPG) += rcar-gen3-cpg.o +obj-$(CONFIG_CLK_RCAR_USB2_CLOCK_SEL) += rcar-usb2-clock-sel.o # Generic obj-$(CONFIG_CLK_RENESAS_CPG_MSSR) += renesas-cpg-mssr.o diff --git a/drivers/clk/renesas/rcar-usb2-clock-sel.c b/drivers/clk/renesas/rcar-usb2-clock-sel.c new file mode 100644 index 000000000000..6cd030a58964 --- /dev/null +++ b/drivers/clk/renesas/rcar-usb2-clock-sel.c @@ -0,0 +1,188 @@ +/* + * Renesas R-Car USB2.0 clock selector + * + * Copyright (C) 2017 Renesas Electronics Corp. + * + * Based on renesas-cpg-mssr.c + * + * Copyright (C) 2015 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define USB20_CLKSET0 0x00 +#define CLKSET0_INTCLK_EN BIT(11) +#define CLKSET0_PRIVATE BIT(0) +#define CLKSET0_EXTAL_ONLY (CLKSET0_INTCLK_EN | CLKSET0_PRIVATE) + +struct usb2_clock_sel_priv { + void __iomem *base; + struct clk_hw hw; + bool extal; + bool xtal; +}; +#define to_priv(_hw) container_of(_hw, struct usb2_clock_sel_priv, hw) + +static void usb2_clock_sel_enable_extal_only(struct usb2_clock_sel_priv *priv) +{ + u16 val = readw(priv->base + USB20_CLKSET0); + + pr_debug("%s: enter %d %d %x\n", __func__, + priv->extal, priv->xtal, val); + + if (priv->extal && !priv->xtal && val != CLKSET0_EXTAL_ONLY) + writew(CLKSET0_EXTAL_ONLY, priv->base + USB20_CLKSET0); +} + +static void usb2_clock_sel_disable_extal_only(struct usb2_clock_sel_priv *priv) +{ + if (priv->extal && !priv->xtal) + writew(CLKSET0_PRIVATE, priv->base + USB20_CLKSET0); +} + +static int usb2_clock_sel_enable(struct clk_hw *hw) +{ + usb2_clock_sel_enable_extal_only(to_priv(hw)); + + return 0; +} + +static void usb2_clock_sel_disable(struct clk_hw *hw) +{ + usb2_clock_sel_disable_extal_only(to_priv(hw)); +} + +/* + * This module seems a mux, but this driver assumes a gate because + * ehci/ohci platform drivers don't support clk_set_parent() for now. + * If this driver acts as a gate, ehci/ohci-platform drivers don't need + * any modification. + */ +static const struct clk_ops usb2_clock_sel_clock_ops = { + .enable = usb2_clock_sel_enable, + .disable = usb2_clock_sel_disable, +}; + +static const struct of_device_id rcar_usb2_clock_sel_match[] = { + { .compatible = "renesas,rcar-gen3-usb2-clock-sel" }, + { } +}; + +static int rcar_usb2_clock_sel_suspend(struct device *dev) +{ + struct usb2_clock_sel_priv *priv = dev_get_drvdata(dev); + + usb2_clock_sel_disable_extal_only(priv); + pm_runtime_put(dev); + + return 0; +} + +static int rcar_usb2_clock_sel_resume(struct device *dev) +{ + struct usb2_clock_sel_priv *priv = dev_get_drvdata(dev); + + pm_runtime_get_sync(dev); + usb2_clock_sel_enable_extal_only(priv); + + return 0; +} + +static int rcar_usb2_clock_sel_remove(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct usb2_clock_sel_priv *priv = platform_get_drvdata(pdev); + + of_clk_del_provider(dev->of_node); + clk_hw_unregister(&priv->hw); + pm_runtime_put(dev); + pm_runtime_disable(dev); + + return 0; +} + +static int rcar_usb2_clock_sel_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct usb2_clock_sel_priv *priv; + struct resource *res; + struct clk *clk; + struct clk_init_data init; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + priv->base = devm_ioremap_resource(dev, res); + if (IS_ERR(priv->base)) + return PTR_ERR(priv->base); + + pm_runtime_enable(dev); + pm_runtime_get_sync(dev); + + clk = devm_clk_get(dev, "usb_extal"); + if (!IS_ERR(clk) && !clk_prepare_enable(clk)) { + priv->extal = !!clk_get_rate(clk); + clk_disable_unprepare(clk); + } + clk = devm_clk_get(dev, "usb_xtal"); + if (!IS_ERR(clk) && !clk_prepare_enable(clk)) { + priv->xtal = !!clk_get_rate(clk); + clk_disable_unprepare(clk); + } + + if (!priv->extal && !priv->xtal) { + dev_err(dev, "This driver needs usb_extal or usb_xtal\n"); + return -ENOENT; + } + + platform_set_drvdata(pdev, priv); + dev_set_drvdata(dev, priv); + + init.name = "rcar_usb2_clock_sel"; + init.ops = &usb2_clock_sel_clock_ops; + init.flags = 0; + init.parent_names = NULL; + init.num_parents = 0; + priv->hw.init = &init; + + clk = clk_register(NULL, &priv->hw); + if (IS_ERR(clk)) + return PTR_ERR(clk); + + return of_clk_add_hw_provider(np, of_clk_hw_simple_get, &priv->hw); +} + +static const struct dev_pm_ops rcar_usb2_clock_sel_pm_ops = { + .suspend = rcar_usb2_clock_sel_suspend, + .resume = rcar_usb2_clock_sel_resume, +}; + +static struct platform_driver rcar_usb2_clock_sel_driver = { + .driver = { + .name = "rcar-usb2-clock-sel", + .of_match_table = rcar_usb2_clock_sel_match, + .pm = &rcar_usb2_clock_sel_pm_ops, + }, + .probe = rcar_usb2_clock_sel_probe, + .remove = rcar_usb2_clock_sel_remove, +}; +builtin_platform_driver(rcar_usb2_clock_sel_driver); + +MODULE_DESCRIPTION("Renesas R-Car USB2 clock selector Driver"); +MODULE_LICENSE("GPL v2"); From c29f82951b974f27e0bc4ce2525db164f86f2e4d Mon Sep 17 00:00:00 2001 From: Hiromitsu Yamasaki Date: Wed, 26 Jul 2017 20:23:39 +0900 Subject: [PATCH 11/11] clk: renesas: r8a7796: Add USB3.0 clock This patch adds USB3.0-IF0 clock for R8A7796 SoC. Signed-off-by: Hiromitsu Yamasaki Signed-off-by: Takeshi Kihara Signed-off-by: Yoshihiro Shimoda Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r8a7796-cpg-mssr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/renesas/r8a7796-cpg-mssr.c b/drivers/clk/renesas/r8a7796-cpg-mssr.c index 22ba3c497aba..e5e7fb212288 100644 --- a/drivers/clk/renesas/r8a7796-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c @@ -138,6 +138,7 @@ static const struct mssr_mod_clk r8a7796_mod_clks[] __initconst = { DEF_MOD("sdif0", 314, R8A7796_CLK_SD0), DEF_MOD("pcie1", 318, R8A7796_CLK_S3D1), DEF_MOD("pcie0", 319, R8A7796_CLK_S3D1), + DEF_MOD("usb3-if0", 328, R8A7796_CLK_S3D1), DEF_MOD("usb-dmac0", 330, R8A7796_CLK_S3D1), DEF_MOD("usb-dmac1", 331, R8A7796_CLK_S3D1), DEF_MOD("rwdt", 402, R8A7796_CLK_R),