Merge branch 'drm-fixes-5.2' of git://people.freedesktop.org/~agd5f/linux into drm...
[sfrench/cifs-2.6.git] / drivers / clk / sunxi-ng / ccu-sun8i-r.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2016 Icenowy Zheng <icenowy@aosc.xyz>
4  */
5
6 #include <linux/clk-provider.h>
7 #include <linux/of_address.h>
8 #include <linux/platform_device.h>
9
10 #include "ccu_common.h"
11 #include "ccu_reset.h"
12
13 #include "ccu_div.h"
14 #include "ccu_gate.h"
15 #include "ccu_mp.h"
16 #include "ccu_nm.h"
17
18 #include "ccu-sun8i-r.h"
19
20 static const char * const ar100_parents[] = { "osc32k", "osc24M",
21                                              "pll-periph0", "iosc" };
22 static const char * const a83t_ar100_parents[] = { "osc16M-d512", "osc24M",
23                                                    "pll-periph0", "iosc" };
24 static const struct ccu_mux_var_prediv ar100_predivs[] = {
25         { .index = 2, .shift = 8, .width = 5 },
26 };
27
28 static struct ccu_div ar100_clk = {
29         .div            = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
30
31         .mux            = {
32                 .shift  = 16,
33                 .width  = 2,
34
35                 .var_predivs    = ar100_predivs,
36                 .n_var_predivs  = ARRAY_SIZE(ar100_predivs),
37         },
38
39         .common         = {
40                 .reg            = 0x00,
41                 .features       = CCU_FEATURE_VARIABLE_PREDIV,
42                 .hw.init        = CLK_HW_INIT_PARENTS("ar100",
43                                                       ar100_parents,
44                                                       &ccu_div_ops,
45                                                       0),
46         },
47 };
48
49 static struct ccu_div a83t_ar100_clk = {
50         .div            = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
51
52         .mux            = {
53                 .shift  = 16,
54                 .width  = 2,
55
56                 .var_predivs    = ar100_predivs,
57                 .n_var_predivs  = ARRAY_SIZE(ar100_predivs),
58         },
59
60         .common         = {
61                 .reg            = 0x00,
62                 .features       = CCU_FEATURE_VARIABLE_PREDIV,
63                 .hw.init        = CLK_HW_INIT_PARENTS("ar100",
64                                                       a83t_ar100_parents,
65                                                       &ccu_div_ops,
66                                                       0),
67         },
68 };
69
70 static CLK_FIXED_FACTOR(ahb0_clk, "ahb0", "ar100", 1, 1, 0);
71
72 static struct ccu_div apb0_clk = {
73         .div            = _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO),
74
75         .common         = {
76                 .reg            = 0x0c,
77                 .hw.init        = CLK_HW_INIT("apb0",
78                                               "ahb0",
79                                               &ccu_div_ops,
80                                               0),
81         },
82 };
83
84 static SUNXI_CCU_M(a83t_apb0_clk, "apb0", "ahb0", 0x0c, 0, 2, 0);
85
86 static SUNXI_CCU_GATE(apb0_pio_clk,     "apb0-pio",     "apb0",
87                       0x28, BIT(0), 0);
88 static SUNXI_CCU_GATE(apb0_ir_clk,      "apb0-ir",      "apb0",
89                       0x28, BIT(1), 0);
90 static SUNXI_CCU_GATE(apb0_timer_clk,   "apb0-timer",   "apb0",
91                       0x28, BIT(2), 0);
92 static SUNXI_CCU_GATE(apb0_rsb_clk,     "apb0-rsb",     "apb0",
93                       0x28, BIT(3), 0);
94 static SUNXI_CCU_GATE(apb0_uart_clk,    "apb0-uart",    "apb0",
95                       0x28, BIT(4), 0);
96 static SUNXI_CCU_GATE(apb0_i2c_clk,     "apb0-i2c",     "apb0",
97                       0x28, BIT(6), 0);
98 static SUNXI_CCU_GATE(apb0_twd_clk,     "apb0-twd",     "apb0",
99                       0x28, BIT(7), 0);
100
101 static const char * const r_mod0_default_parents[] = { "osc32k", "osc24M" };
102 static SUNXI_CCU_MP_WITH_MUX_GATE(ir_clk, "ir",
103                                   r_mod0_default_parents, 0x54,
104                                   0, 4,         /* M */
105                                   16, 2,        /* P */
106                                   24, 2,        /* mux */
107                                   BIT(31),      /* gate */
108                                   0);
109
110 static const char *const a83t_r_mod0_parents[] = { "osc16M", "osc24M" };
111 static const struct ccu_mux_fixed_prediv a83t_ir_predivs[] = {
112         { .index = 0, .div = 16 },
113 };
114 static struct ccu_mp a83t_ir_clk = {
115         .enable = BIT(31),
116
117         .m      = _SUNXI_CCU_DIV(0, 4),
118         .p      = _SUNXI_CCU_DIV(16, 2),
119
120         .mux    = {
121                 .shift  = 24,
122                 .width  = 2,
123                 .fixed_predivs  = a83t_ir_predivs,
124                 .n_predivs      = ARRAY_SIZE(a83t_ir_predivs),
125         },
126
127         .common         = {
128                 .reg            = 0x54,
129                 .features       = CCU_FEATURE_VARIABLE_PREDIV,
130                 .hw.init        = CLK_HW_INIT_PARENTS("ir",
131                                                       a83t_r_mod0_parents,
132                                                       &ccu_mp_ops,
133                                                       0),
134         },
135 };
136
137 static struct ccu_common *sun8i_a83t_r_ccu_clks[] = {
138         &a83t_ar100_clk.common,
139         &a83t_apb0_clk.common,
140         &apb0_pio_clk.common,
141         &apb0_ir_clk.common,
142         &apb0_timer_clk.common,
143         &apb0_rsb_clk.common,
144         &apb0_uart_clk.common,
145         &apb0_i2c_clk.common,
146         &apb0_twd_clk.common,
147         &a83t_ir_clk.common,
148 };
149
150 static struct ccu_common *sun8i_h3_r_ccu_clks[] = {
151         &ar100_clk.common,
152         &apb0_clk.common,
153         &apb0_pio_clk.common,
154         &apb0_ir_clk.common,
155         &apb0_timer_clk.common,
156         &apb0_uart_clk.common,
157         &apb0_i2c_clk.common,
158         &apb0_twd_clk.common,
159         &ir_clk.common,
160 };
161
162 static struct ccu_common *sun50i_a64_r_ccu_clks[] = {
163         &ar100_clk.common,
164         &apb0_clk.common,
165         &apb0_pio_clk.common,
166         &apb0_ir_clk.common,
167         &apb0_timer_clk.common,
168         &apb0_rsb_clk.common,
169         &apb0_uart_clk.common,
170         &apb0_i2c_clk.common,
171         &apb0_twd_clk.common,
172         &ir_clk.common,
173 };
174
175 static struct clk_hw_onecell_data sun8i_a83t_r_hw_clks = {
176         .hws    = {
177                 [CLK_AR100]             = &a83t_ar100_clk.common.hw,
178                 [CLK_AHB0]              = &ahb0_clk.hw,
179                 [CLK_APB0]              = &a83t_apb0_clk.common.hw,
180                 [CLK_APB0_PIO]          = &apb0_pio_clk.common.hw,
181                 [CLK_APB0_IR]           = &apb0_ir_clk.common.hw,
182                 [CLK_APB0_TIMER]        = &apb0_timer_clk.common.hw,
183                 [CLK_APB0_RSB]          = &apb0_rsb_clk.common.hw,
184                 [CLK_APB0_UART]         = &apb0_uart_clk.common.hw,
185                 [CLK_APB0_I2C]          = &apb0_i2c_clk.common.hw,
186                 [CLK_APB0_TWD]          = &apb0_twd_clk.common.hw,
187                 [CLK_IR]                = &a83t_ir_clk.common.hw,
188         },
189         .num    = CLK_NUMBER,
190 };
191
192 static struct clk_hw_onecell_data sun8i_h3_r_hw_clks = {
193         .hws    = {
194                 [CLK_AR100]             = &ar100_clk.common.hw,
195                 [CLK_AHB0]              = &ahb0_clk.hw,
196                 [CLK_APB0]              = &apb0_clk.common.hw,
197                 [CLK_APB0_PIO]          = &apb0_pio_clk.common.hw,
198                 [CLK_APB0_IR]           = &apb0_ir_clk.common.hw,
199                 [CLK_APB0_TIMER]        = &apb0_timer_clk.common.hw,
200                 [CLK_APB0_UART]         = &apb0_uart_clk.common.hw,
201                 [CLK_APB0_I2C]          = &apb0_i2c_clk.common.hw,
202                 [CLK_APB0_TWD]          = &apb0_twd_clk.common.hw,
203                 [CLK_IR]                = &ir_clk.common.hw,
204         },
205         .num    = CLK_NUMBER,
206 };
207
208 static struct clk_hw_onecell_data sun50i_a64_r_hw_clks = {
209         .hws    = {
210                 [CLK_AR100]             = &ar100_clk.common.hw,
211                 [CLK_AHB0]              = &ahb0_clk.hw,
212                 [CLK_APB0]              = &apb0_clk.common.hw,
213                 [CLK_APB0_PIO]          = &apb0_pio_clk.common.hw,
214                 [CLK_APB0_IR]           = &apb0_ir_clk.common.hw,
215                 [CLK_APB0_TIMER]        = &apb0_timer_clk.common.hw,
216                 [CLK_APB0_RSB]          = &apb0_rsb_clk.common.hw,
217                 [CLK_APB0_UART]         = &apb0_uart_clk.common.hw,
218                 [CLK_APB0_I2C]          = &apb0_i2c_clk.common.hw,
219                 [CLK_APB0_TWD]          = &apb0_twd_clk.common.hw,
220                 [CLK_IR]                = &ir_clk.common.hw,
221         },
222         .num    = CLK_NUMBER,
223 };
224
225 static struct ccu_reset_map sun8i_a83t_r_ccu_resets[] = {
226         [RST_APB0_IR]           =  { 0xb0, BIT(1) },
227         [RST_APB0_TIMER]        =  { 0xb0, BIT(2) },
228         [RST_APB0_RSB]          =  { 0xb0, BIT(3) },
229         [RST_APB0_UART]         =  { 0xb0, BIT(4) },
230         [RST_APB0_I2C]          =  { 0xb0, BIT(6) },
231 };
232
233 static struct ccu_reset_map sun8i_h3_r_ccu_resets[] = {
234         [RST_APB0_IR]           =  { 0xb0, BIT(1) },
235         [RST_APB0_TIMER]        =  { 0xb0, BIT(2) },
236         [RST_APB0_UART]         =  { 0xb0, BIT(4) },
237         [RST_APB0_I2C]          =  { 0xb0, BIT(6) },
238 };
239
240 static struct ccu_reset_map sun50i_a64_r_ccu_resets[] = {
241         [RST_APB0_IR]           =  { 0xb0, BIT(1) },
242         [RST_APB0_TIMER]        =  { 0xb0, BIT(2) },
243         [RST_APB0_RSB]          =  { 0xb0, BIT(3) },
244         [RST_APB0_UART]         =  { 0xb0, BIT(4) },
245         [RST_APB0_I2C]          =  { 0xb0, BIT(6) },
246 };
247
248 static const struct sunxi_ccu_desc sun8i_a83t_r_ccu_desc = {
249         .ccu_clks       = sun8i_a83t_r_ccu_clks,
250         .num_ccu_clks   = ARRAY_SIZE(sun8i_a83t_r_ccu_clks),
251
252         .hw_clks        = &sun8i_a83t_r_hw_clks,
253
254         .resets         = sun8i_a83t_r_ccu_resets,
255         .num_resets     = ARRAY_SIZE(sun8i_a83t_r_ccu_resets),
256 };
257
258 static const struct sunxi_ccu_desc sun8i_h3_r_ccu_desc = {
259         .ccu_clks       = sun8i_h3_r_ccu_clks,
260         .num_ccu_clks   = ARRAY_SIZE(sun8i_h3_r_ccu_clks),
261
262         .hw_clks        = &sun8i_h3_r_hw_clks,
263
264         .resets         = sun8i_h3_r_ccu_resets,
265         .num_resets     = ARRAY_SIZE(sun8i_h3_r_ccu_resets),
266 };
267
268 static const struct sunxi_ccu_desc sun50i_a64_r_ccu_desc = {
269         .ccu_clks       = sun50i_a64_r_ccu_clks,
270         .num_ccu_clks   = ARRAY_SIZE(sun50i_a64_r_ccu_clks),
271
272         .hw_clks        = &sun50i_a64_r_hw_clks,
273
274         .resets         = sun50i_a64_r_ccu_resets,
275         .num_resets     = ARRAY_SIZE(sun50i_a64_r_ccu_resets),
276 };
277
278 static void __init sunxi_r_ccu_init(struct device_node *node,
279                                     const struct sunxi_ccu_desc *desc)
280 {
281         void __iomem *reg;
282
283         reg = of_io_request_and_map(node, 0, of_node_full_name(node));
284         if (IS_ERR(reg)) {
285                 pr_err("%pOF: Could not map the clock registers\n", node);
286                 return;
287         }
288
289         sunxi_ccu_probe(node, reg, desc);
290 }
291
292 static void __init sun8i_a83t_r_ccu_setup(struct device_node *node)
293 {
294         sunxi_r_ccu_init(node, &sun8i_a83t_r_ccu_desc);
295 }
296 CLK_OF_DECLARE(sun8i_a83t_r_ccu, "allwinner,sun8i-a83t-r-ccu",
297                sun8i_a83t_r_ccu_setup);
298
299 static void __init sun8i_h3_r_ccu_setup(struct device_node *node)
300 {
301         sunxi_r_ccu_init(node, &sun8i_h3_r_ccu_desc);
302 }
303 CLK_OF_DECLARE(sun8i_h3_r_ccu, "allwinner,sun8i-h3-r-ccu",
304                sun8i_h3_r_ccu_setup);
305
306 static void __init sun50i_a64_r_ccu_setup(struct device_node *node)
307 {
308         sunxi_r_ccu_init(node, &sun50i_a64_r_ccu_desc);
309 }
310 CLK_OF_DECLARE(sun50i_a64_r_ccu, "allwinner,sun50i-a64-r-ccu",
311                sun50i_a64_r_ccu_setup);