.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
---|
1 | 2 | /* |
---|
2 | 3 | * r8a77970 Clock Pulse Generator / Module Standby and Software Reset |
---|
3 | 4 | * |
---|
4 | | - * Copyright (C) 2017 Cogent Embedded Inc. |
---|
| 5 | + * Copyright (C) 2017-2018 Cogent Embedded Inc. |
---|
5 | 6 | * |
---|
6 | 7 | * Based on r8a7795-cpg-mssr.c |
---|
7 | 8 | * |
---|
8 | 9 | * Copyright (C) 2015 Glider bvba |
---|
9 | | - * |
---|
10 | | - * This program is free software; you can redistribute it and/or modify |
---|
11 | | - * it under the terms of the GNU General Public License as published by |
---|
12 | | - * the Free Software Foundation; version 2 of the License. |
---|
13 | 10 | */ |
---|
14 | 11 | |
---|
| 12 | +#include <linux/clk-provider.h> |
---|
15 | 13 | #include <linux/device.h> |
---|
16 | 14 | #include <linux/init.h> |
---|
17 | 15 | #include <linux/kernel.h> |
---|
.. | .. |
---|
21 | 19 | |
---|
22 | 20 | #include "renesas-cpg-mssr.h" |
---|
23 | 21 | #include "rcar-gen3-cpg.h" |
---|
| 22 | + |
---|
| 23 | +#define CPG_SD0CKCR 0x0074 |
---|
| 24 | + |
---|
| 25 | +enum r8a77970_clk_types { |
---|
| 26 | + CLK_TYPE_R8A77970_SD0H = CLK_TYPE_GEN3_SOC_BASE, |
---|
| 27 | + CLK_TYPE_R8A77970_SD0, |
---|
| 28 | +}; |
---|
24 | 29 | |
---|
25 | 30 | enum clk_ids { |
---|
26 | 31 | /* Core Clock Outputs exported to DT */ |
---|
.. | .. |
---|
40 | 45 | |
---|
41 | 46 | /* Module Clocks */ |
---|
42 | 47 | MOD_CLK_BASE |
---|
| 48 | +}; |
---|
| 49 | + |
---|
| 50 | +static spinlock_t cpg_lock; |
---|
| 51 | + |
---|
| 52 | +static const struct clk_div_table cpg_sd0h_div_table[] = { |
---|
| 53 | + { 0, 2 }, { 1, 3 }, { 2, 4 }, { 3, 6 }, |
---|
| 54 | + { 4, 8 }, { 5, 12 }, { 6, 16 }, { 7, 18 }, |
---|
| 55 | + { 8, 24 }, { 10, 36 }, { 11, 48 }, { 0, 0 }, |
---|
| 56 | +}; |
---|
| 57 | + |
---|
| 58 | +static const struct clk_div_table cpg_sd0_div_table[] = { |
---|
| 59 | + { 4, 8 }, { 5, 12 }, { 6, 16 }, { 7, 18 }, |
---|
| 60 | + { 8, 24 }, { 10, 36 }, { 11, 48 }, { 12, 10 }, |
---|
| 61 | + { 0, 0 }, |
---|
43 | 62 | }; |
---|
44 | 63 | |
---|
45 | 64 | static const struct cpg_core_clk r8a77970_core_clks[] __initconst = { |
---|
.. | .. |
---|
68 | 87 | DEF_FIXED("s2d2", R8A77970_CLK_S2D2, CLK_PLL1_DIV2, 12, 1), |
---|
69 | 88 | DEF_FIXED("s2d4", R8A77970_CLK_S2D4, CLK_PLL1_DIV2, 24, 1), |
---|
70 | 89 | |
---|
| 90 | + DEF_BASE("sd0h", R8A77970_CLK_SD0H, CLK_TYPE_R8A77970_SD0H, |
---|
| 91 | + CLK_PLL1_DIV2), |
---|
| 92 | + DEF_BASE("sd0", R8A77970_CLK_SD0, CLK_TYPE_R8A77970_SD0, CLK_PLL1_DIV2), |
---|
| 93 | + |
---|
| 94 | + DEF_FIXED("rpc", R8A77970_CLK_RPC, CLK_PLL1_DIV2, 5, 1), |
---|
| 95 | + DEF_FIXED("rpcd2", R8A77970_CLK_RPCD2, CLK_PLL1_DIV2, 10, 1), |
---|
| 96 | + |
---|
71 | 97 | DEF_FIXED("cl", R8A77970_CLK_CL, CLK_PLL1_DIV2, 48, 1), |
---|
72 | 98 | DEF_FIXED("cp", R8A77970_CLK_CP, CLK_EXTAL, 2, 1), |
---|
| 99 | + DEF_FIXED("cpex", R8A77970_CLK_CPEX, CLK_EXTAL, 2, 1), |
---|
73 | 100 | |
---|
74 | 101 | DEF_DIV6P1("canfd", R8A77970_CLK_CANFD, CLK_PLL1_DIV4, 0x244), |
---|
75 | 102 | DEF_DIV6P1("mso", R8A77970_CLK_MSO, CLK_PLL1_DIV4, 0x014), |
---|
.. | .. |
---|
80 | 107 | }; |
---|
81 | 108 | |
---|
82 | 109 | static const struct mssr_mod_clk r8a77970_mod_clks[] __initconst = { |
---|
| 110 | + DEF_MOD("tmu4", 121, R8A77970_CLK_S2D2), |
---|
| 111 | + DEF_MOD("tmu3", 122, R8A77970_CLK_S2D2), |
---|
| 112 | + DEF_MOD("tmu2", 123, R8A77970_CLK_S2D2), |
---|
| 113 | + DEF_MOD("tmu1", 124, R8A77970_CLK_S2D2), |
---|
| 114 | + DEF_MOD("tmu0", 125, R8A77970_CLK_CP), |
---|
83 | 115 | DEF_MOD("ivcp1e", 127, R8A77970_CLK_S2D1), |
---|
84 | 116 | DEF_MOD("scif4", 203, R8A77970_CLK_S2D4), |
---|
85 | 117 | DEF_MOD("scif3", 204, R8A77970_CLK_S2D4), |
---|
.. | .. |
---|
92 | 124 | DEF_MOD("mfis", 213, R8A77970_CLK_S2D2), |
---|
93 | 125 | DEF_MOD("sys-dmac2", 217, R8A77970_CLK_S2D1), |
---|
94 | 126 | DEF_MOD("sys-dmac1", 218, R8A77970_CLK_S2D1), |
---|
| 127 | + DEF_MOD("cmt3", 300, R8A77970_CLK_R), |
---|
| 128 | + DEF_MOD("cmt2", 301, R8A77970_CLK_R), |
---|
| 129 | + DEF_MOD("cmt1", 302, R8A77970_CLK_R), |
---|
| 130 | + DEF_MOD("cmt0", 303, R8A77970_CLK_R), |
---|
| 131 | + DEF_MOD("tpu0", 304, R8A77970_CLK_S2D4), |
---|
| 132 | + DEF_MOD("sd-if", 314, R8A77970_CLK_SD0), |
---|
95 | 133 | DEF_MOD("rwdt", 402, R8A77970_CLK_R), |
---|
96 | 134 | DEF_MOD("intc-ex", 407, R8A77970_CLK_CP), |
---|
97 | 135 | DEF_MOD("intc-ap", 408, R8A77970_CLK_S2D1), |
---|
.. | .. |
---|
118 | 156 | DEF_MOD("gpio1", 911, R8A77970_CLK_CP), |
---|
119 | 157 | DEF_MOD("gpio0", 912, R8A77970_CLK_CP), |
---|
120 | 158 | DEF_MOD("can-fd", 914, R8A77970_CLK_S2D2), |
---|
| 159 | + DEF_MOD("rpc-if", 917, R8A77970_CLK_RPC), |
---|
121 | 160 | DEF_MOD("i2c4", 927, R8A77970_CLK_S2D2), |
---|
122 | 161 | DEF_MOD("i2c3", 928, R8A77970_CLK_S2D2), |
---|
123 | 162 | DEF_MOD("i2c2", 929, R8A77970_CLK_S2D2), |
---|
.. | .. |
---|
126 | 165 | }; |
---|
127 | 166 | |
---|
128 | 167 | static const unsigned int r8a77970_crit_mod_clks[] __initconst = { |
---|
| 168 | + MOD_CLK_ID(402), /* RWDT */ |
---|
129 | 169 | MOD_CLK_ID(408), /* INTC-AP (GIC) */ |
---|
130 | 170 | }; |
---|
131 | | - |
---|
132 | 171 | |
---|
133 | 172 | /* |
---|
134 | 173 | * CPG Clock Data |
---|
.. | .. |
---|
173 | 212 | if (error) |
---|
174 | 213 | return error; |
---|
175 | 214 | |
---|
| 215 | + spin_lock_init(&cpg_lock); |
---|
| 216 | + |
---|
176 | 217 | cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)]; |
---|
177 | 218 | |
---|
178 | 219 | return rcar_gen3_cpg_init(cpg_pll_config, CLK_EXTALR, cpg_mode); |
---|
| 220 | +} |
---|
| 221 | + |
---|
| 222 | +static struct clk * __init r8a77970_cpg_clk_register(struct device *dev, |
---|
| 223 | + const struct cpg_core_clk *core, const struct cpg_mssr_info *info, |
---|
| 224 | + struct clk **clks, void __iomem *base, |
---|
| 225 | + struct raw_notifier_head *notifiers) |
---|
| 226 | +{ |
---|
| 227 | + const struct clk_div_table *table; |
---|
| 228 | + const struct clk *parent; |
---|
| 229 | + unsigned int shift; |
---|
| 230 | + |
---|
| 231 | + switch (core->type) { |
---|
| 232 | + case CLK_TYPE_R8A77970_SD0H: |
---|
| 233 | + table = cpg_sd0h_div_table; |
---|
| 234 | + shift = 8; |
---|
| 235 | + break; |
---|
| 236 | + case CLK_TYPE_R8A77970_SD0: |
---|
| 237 | + table = cpg_sd0_div_table; |
---|
| 238 | + shift = 4; |
---|
| 239 | + break; |
---|
| 240 | + default: |
---|
| 241 | + return rcar_gen3_cpg_clk_register(dev, core, info, clks, base, |
---|
| 242 | + notifiers); |
---|
| 243 | + } |
---|
| 244 | + |
---|
| 245 | + parent = clks[core->parent]; |
---|
| 246 | + if (IS_ERR(parent)) |
---|
| 247 | + return ERR_CAST(parent); |
---|
| 248 | + |
---|
| 249 | + return clk_register_divider_table(NULL, core->name, |
---|
| 250 | + __clk_get_name(parent), 0, |
---|
| 251 | + base + CPG_SD0CKCR, |
---|
| 252 | + shift, 4, 0, table, &cpg_lock); |
---|
179 | 253 | } |
---|
180 | 254 | |
---|
181 | 255 | const struct cpg_mssr_info r8a77970_cpg_mssr_info __initconst = { |
---|
.. | .. |
---|
196 | 270 | |
---|
197 | 271 | /* Callbacks */ |
---|
198 | 272 | .init = r8a77970_cpg_mssr_init, |
---|
199 | | - .cpg_clk_register = rcar_gen3_cpg_clk_register, |
---|
| 273 | + .cpg_clk_register = r8a77970_cpg_clk_register, |
---|
200 | 274 | }; |
---|