clk: renesas: rcar-gen3: Add support for SCCG/Clean peripheral clocks
authorGeert Uytterhoeven <geert+renesas@glider.be>
Wed, 19 Jul 2017 15:39:54 +0000 (17:39 +0200)
committerGeert Uytterhoeven <geert+renesas@glider.be>
Wed, 16 Aug 2017 07:51:47 +0000 (09:51 +0200)
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 <geert+renesas@glider.be>
Acked-by: Stephen Boyd <sboyd@codeaurora.org>
drivers/clk/renesas/rcar-gen3-cpg.c
drivers/clk/renesas/rcar-gen3-cpg.h

index 3f922fea9671fb4c279d36be9bd0323889b7c562..9511058165475dd7c8563aaa1409d1dd5ada5cc1 100644 (file)
@@ -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);
        }
index 4eaf02955580a938edbf8c5b83996ee6476502c2..d756ef8b78eb6c02d9fee43dd6670cda36df53bb 100644 (file)
@@ -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;