Merge branch 'core/urgent' into x86/urgent, to pick up objtool fix
[sfrench/cifs-2.6.git] / drivers / clk / renesas / r8a77970-cpg-mssr.c
index f55842917e8dd36ab86135113ffb468cd60798ba..2015e45543e948f23aa70160a4a5b34f9f61355d 100644 (file)
@@ -1,17 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * r8a77970 Clock Pulse Generator / Module Standby and Software Reset
  *
- * Copyright (C) 2017 Cogent Embedded Inc.
+ * Copyright (C) 2017-2018 Cogent Embedded Inc.
  *
  * Based on r8a7795-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 <linux/clk-provider.h>
 #include <linux/device.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include "renesas-cpg-mssr.h"
 #include "rcar-gen3-cpg.h"
 
+#define CPG_SD0CKCR            0x0074
+
+enum r8a77970_clk_types {
+       CLK_TYPE_R8A77970_SD0H = CLK_TYPE_GEN3_SOC_BASE,
+       CLK_TYPE_R8A77970_SD0,
+};
+
 enum clk_ids {
        /* Core Clock Outputs exported to DT */
        LAST_DT_CORE_CLK = R8A77970_CLK_OSC,
@@ -42,6 +47,20 @@ enum clk_ids {
        MOD_CLK_BASE
 };
 
+static spinlock_t cpg_lock;
+
+static const struct clk_div_table cpg_sd0h_div_table[] = {
+       {  0,  2 }, {  1,  3 }, {  2,  4 }, {  3,  6 },
+       {  4,  8 }, {  5, 12 }, {  6, 16 }, {  7, 18 },
+       {  8, 24 }, { 10, 36 }, { 11, 48 }, {  0,  0 },
+};
+
+static const struct clk_div_table cpg_sd0_div_table[] = {
+       {  4,  8 }, {  5, 12 }, {  6, 16 }, {  7, 18 },
+       {  8, 24 }, { 10, 36 }, { 11, 48 }, { 12, 10 },
+       {  0,  0 },
+};
+
 static const struct cpg_core_clk r8a77970_core_clks[] __initconst = {
        /* External Clock Inputs */
        DEF_INPUT("extal",      CLK_EXTAL),
@@ -68,6 +87,10 @@ static const struct cpg_core_clk r8a77970_core_clks[] __initconst = {
        DEF_FIXED("s2d2",       R8A77970_CLK_S2D2,  CLK_PLL1_DIV2, 12, 1),
        DEF_FIXED("s2d4",       R8A77970_CLK_S2D4,  CLK_PLL1_DIV2, 24, 1),
 
+       DEF_BASE("sd0h", R8A77970_CLK_SD0H, CLK_TYPE_R8A77970_SD0H,
+                CLK_PLL1_DIV2),
+       DEF_BASE("sd0", R8A77970_CLK_SD0, CLK_TYPE_R8A77970_SD0, CLK_PLL1_DIV2),
+
        DEF_FIXED("cl",         R8A77970_CLK_CL,    CLK_PLL1_DIV2, 48, 1),
        DEF_FIXED("cp",         R8A77970_CLK_CP,    CLK_EXTAL,      2, 1),
 
@@ -80,6 +103,11 @@ static const struct cpg_core_clk r8a77970_core_clks[] __initconst = {
 };
 
 static const struct mssr_mod_clk r8a77970_mod_clks[] __initconst = {
+       DEF_MOD("tmu4",                  121,   R8A77970_CLK_S2D2),
+       DEF_MOD("tmu3",                  122,   R8A77970_CLK_S2D2),
+       DEF_MOD("tmu2",                  123,   R8A77970_CLK_S2D2),
+       DEF_MOD("tmu1",                  124,   R8A77970_CLK_S2D2),
+       DEF_MOD("tmu0",                  125,   R8A77970_CLK_CP),
        DEF_MOD("ivcp1e",                127,   R8A77970_CLK_S2D1),
        DEF_MOD("scif4",                 203,   R8A77970_CLK_S2D4),
        DEF_MOD("scif3",                 204,   R8A77970_CLK_S2D4),
@@ -92,6 +120,12 @@ static const struct mssr_mod_clk r8a77970_mod_clks[] __initconst = {
        DEF_MOD("mfis",                  213,   R8A77970_CLK_S2D2),
        DEF_MOD("sys-dmac2",             217,   R8A77970_CLK_S2D1),
        DEF_MOD("sys-dmac1",             218,   R8A77970_CLK_S2D1),
+       DEF_MOD("cmt3",                  300,   R8A77970_CLK_R),
+       DEF_MOD("cmt2",                  301,   R8A77970_CLK_R),
+       DEF_MOD("cmt1",                  302,   R8A77970_CLK_R),
+       DEF_MOD("cmt0",                  303,   R8A77970_CLK_R),
+       DEF_MOD("tpu0",                  304,   R8A77970_CLK_S2D4),
+       DEF_MOD("sd-if",                 314,   R8A77970_CLK_SD0),
        DEF_MOD("rwdt",                  402,   R8A77970_CLK_R),
        DEF_MOD("intc-ex",               407,   R8A77970_CLK_CP),
        DEF_MOD("intc-ap",               408,   R8A77970_CLK_S2D1),
@@ -173,11 +207,46 @@ static int __init r8a77970_cpg_mssr_init(struct device *dev)
        if (error)
                return error;
 
+       spin_lock_init(&cpg_lock);
+
        cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)];
 
        return rcar_gen3_cpg_init(cpg_pll_config, CLK_EXTALR, cpg_mode);
 }
 
+static struct clk * __init r8a77970_cpg_clk_register(struct device *dev,
+       const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
+       struct clk **clks, void __iomem *base,
+       struct raw_notifier_head *notifiers)
+{
+       const struct clk_div_table *table;
+       const struct clk *parent;
+       unsigned int shift;
+
+       switch (core->type) {
+       case CLK_TYPE_R8A77970_SD0H:
+               table = cpg_sd0h_div_table;
+               shift = 8;
+               break;
+       case CLK_TYPE_R8A77970_SD0:
+               table = cpg_sd0_div_table;
+               shift = 4;
+               break;
+       default:
+               return rcar_gen3_cpg_clk_register(dev, core, info, clks, base,
+                                                 notifiers);
+       }
+
+       parent = clks[core->parent];
+       if (IS_ERR(parent))
+               return ERR_CAST(parent);
+
+       return clk_register_divider_table(NULL, core->name,
+                                         __clk_get_name(parent), 0,
+                                         base + CPG_SD0CKCR,
+                                         shift, 4, 0, table, &cpg_lock);
+}
+
 const struct cpg_mssr_info r8a77970_cpg_mssr_info __initconst = {
        /* Core Clocks */
        .core_clks = r8a77970_core_clks,
@@ -196,5 +265,5 @@ const struct cpg_mssr_info r8a77970_cpg_mssr_info __initconst = {
 
        /* Callbacks */
        .init = r8a77970_cpg_mssr_init,
-       .cpg_clk_register = rcar_gen3_cpg_clk_register,
+       .cpg_clk_register = r8a77970_cpg_clk_register,
 };