Merge tag 'v6.2-rc1' into media_tree
[linux-block.git] / drivers / clk / rockchip / clk.h
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * Copyright (c) 2014 MundoReader S.L.
4  * Author: Heiko Stuebner <heiko@sntech.de>
5  *
6  * Copyright (c) 2015 Rockchip Electronics Co. Ltd.
7  * Author: Xing Zheng <zhengxing@rock-chips.com>
8  *
9  * based on
10  *
11  * samsung/clk.h
12  * Copyright (c) 2013 Samsung Electronics Co., Ltd.
13  * Copyright (c) 2013 Linaro Ltd.
14  * Author: Thomas Abraham <thomas.ab@samsung.com>
15  */
16
17 #ifndef CLK_ROCKCHIP_CLK_H
18 #define CLK_ROCKCHIP_CLK_H
19
20 #include <linux/io.h>
21 #include <linux/clk-provider.h>
22
23 struct clk;
24
25 #define HIWORD_UPDATE(val, mask, shift) \
26                 ((val) << (shift) | (mask) << ((shift) + 16))
27
28 /* register positions shared by PX30, RV1108, RK2928, RK3036, RK3066, RK3188 and RK3228 */
29 #define BOOST_PLL_H_CON(x)              ((x) * 0x4)
30 #define BOOST_CLK_CON                   0x0008
31 #define BOOST_BOOST_CON                 0x000c
32 #define BOOST_SWITCH_CNT                0x0010
33 #define BOOST_HIGH_PERF_CNT0            0x0014
34 #define BOOST_HIGH_PERF_CNT1            0x0018
35 #define BOOST_STATIS_THRESHOLD          0x001c
36 #define BOOST_SHORT_SWITCH_CNT          0x0020
37 #define BOOST_SWITCH_THRESHOLD          0x0024
38 #define BOOST_FSM_STATUS                0x0028
39 #define BOOST_PLL_L_CON(x)              ((x) * 0x4 + 0x2c)
40 #define BOOST_RECOVERY_MASK             0x1
41 #define BOOST_RECOVERY_SHIFT            1
42 #define BOOST_SW_CTRL_MASK              0x1
43 #define BOOST_SW_CTRL_SHIFT             2
44 #define BOOST_LOW_FREQ_EN_MASK          0x1
45 #define BOOST_LOW_FREQ_EN_SHIFT         3
46 #define BOOST_BUSY_STATE                BIT(8)
47
48 #define PX30_PLL_CON(x)                 ((x) * 0x4)
49 #define PX30_CLKSEL_CON(x)              ((x) * 0x4 + 0x100)
50 #define PX30_CLKGATE_CON(x)             ((x) * 0x4 + 0x200)
51 #define PX30_GLB_SRST_FST               0xb8
52 #define PX30_GLB_SRST_SND               0xbc
53 #define PX30_SOFTRST_CON(x)             ((x) * 0x4 + 0x300)
54 #define PX30_MODE_CON                   0xa0
55 #define PX30_MISC_CON                   0xa4
56 #define PX30_SDMMC_CON0                 0x380
57 #define PX30_SDMMC_CON1                 0x384
58 #define PX30_SDIO_CON0                  0x388
59 #define PX30_SDIO_CON1                  0x38c
60 #define PX30_EMMC_CON0                  0x390
61 #define PX30_EMMC_CON1                  0x394
62
63 #define PX30_PMU_PLL_CON(x)             ((x) * 0x4)
64 #define PX30_PMU_CLKSEL_CON(x)          ((x) * 0x4 + 0x40)
65 #define PX30_PMU_CLKGATE_CON(x)         ((x) * 0x4 + 0x80)
66 #define PX30_PMU_MODE                   0x0020
67
68 #define RV1108_PLL_CON(x)               ((x) * 0x4)
69 #define RV1108_CLKSEL_CON(x)            ((x) * 0x4 + 0x60)
70 #define RV1108_CLKGATE_CON(x)           ((x) * 0x4 + 0x120)
71 #define RV1108_SOFTRST_CON(x)           ((x) * 0x4 + 0x180)
72 #define RV1108_GLB_SRST_FST             0x1c0
73 #define RV1108_GLB_SRST_SND             0x1c4
74 #define RV1108_MISC_CON                 0x1cc
75 #define RV1108_SDMMC_CON0               0x1d8
76 #define RV1108_SDMMC_CON1               0x1dc
77 #define RV1108_SDIO_CON0                0x1e0
78 #define RV1108_SDIO_CON1                0x1e4
79 #define RV1108_EMMC_CON0                0x1e8
80 #define RV1108_EMMC_CON1                0x1ec
81
82 #define RV1126_PMU_MODE                 0x0
83 #define RV1126_PMU_PLL_CON(x)           ((x) * 0x4 + 0x10)
84 #define RV1126_PMU_CLKSEL_CON(x)        ((x) * 0x4 + 0x100)
85 #define RV1126_PMU_CLKGATE_CON(x)       ((x) * 0x4 + 0x180)
86 #define RV1126_PMU_SOFTRST_CON(x)       ((x) * 0x4 + 0x200)
87 #define RV1126_PLL_CON(x)               ((x) * 0x4)
88 #define RV1126_MODE_CON                 0x90
89 #define RV1126_CLKSEL_CON(x)            ((x) * 0x4 + 0x100)
90 #define RV1126_CLKGATE_CON(x)           ((x) * 0x4 + 0x280)
91 #define RV1126_SOFTRST_CON(x)           ((x) * 0x4 + 0x300)
92 #define RV1126_GLB_SRST_FST             0x408
93 #define RV1126_GLB_SRST_SND             0x40c
94 #define RV1126_SDMMC_CON0               0x440
95 #define RV1126_SDMMC_CON1               0x444
96 #define RV1126_SDIO_CON0                0x448
97 #define RV1126_SDIO_CON1                0x44c
98 #define RV1126_EMMC_CON0                0x450
99 #define RV1126_EMMC_CON1                0x454
100
101 #define RK2928_PLL_CON(x)               ((x) * 0x4)
102 #define RK2928_MODE_CON         0x40
103 #define RK2928_CLKSEL_CON(x)    ((x) * 0x4 + 0x44)
104 #define RK2928_CLKGATE_CON(x)   ((x) * 0x4 + 0xd0)
105 #define RK2928_GLB_SRST_FST             0x100
106 #define RK2928_GLB_SRST_SND             0x104
107 #define RK2928_SOFTRST_CON(x)   ((x) * 0x4 + 0x110)
108 #define RK2928_MISC_CON         0x134
109
110 #define RK3036_SDMMC_CON0               0x144
111 #define RK3036_SDMMC_CON1               0x148
112 #define RK3036_SDIO_CON0                0x14c
113 #define RK3036_SDIO_CON1                0x150
114 #define RK3036_EMMC_CON0                0x154
115 #define RK3036_EMMC_CON1                0x158
116
117 #define RK3228_GLB_SRST_FST             0x1f0
118 #define RK3228_GLB_SRST_SND             0x1f4
119 #define RK3228_SDMMC_CON0               0x1c0
120 #define RK3228_SDMMC_CON1               0x1c4
121 #define RK3228_SDIO_CON0                0x1c8
122 #define RK3228_SDIO_CON1                0x1cc
123 #define RK3228_EMMC_CON0                0x1d8
124 #define RK3228_EMMC_CON1                0x1dc
125
126 #define RK3288_PLL_CON(x)               RK2928_PLL_CON(x)
127 #define RK3288_MODE_CON                 0x50
128 #define RK3288_CLKSEL_CON(x)            ((x) * 0x4 + 0x60)
129 #define RK3288_CLKGATE_CON(x)           ((x) * 0x4 + 0x160)
130 #define RK3288_GLB_SRST_FST             0x1b0
131 #define RK3288_GLB_SRST_SND             0x1b4
132 #define RK3288_SOFTRST_CON(x)           ((x) * 0x4 + 0x1b8)
133 #define RK3288_MISC_CON                 0x1e8
134 #define RK3288_SDMMC_CON0               0x200
135 #define RK3288_SDMMC_CON1               0x204
136 #define RK3288_SDIO0_CON0               0x208
137 #define RK3288_SDIO0_CON1               0x20c
138 #define RK3288_SDIO1_CON0               0x210
139 #define RK3288_SDIO1_CON1               0x214
140 #define RK3288_EMMC_CON0                0x218
141 #define RK3288_EMMC_CON1                0x21c
142
143 #define RK3308_PLL_CON(x)               RK2928_PLL_CON(x)
144 #define RK3308_CLKSEL_CON(x)            ((x) * 0x4 + 0x100)
145 #define RK3308_CLKGATE_CON(x)           ((x) * 0x4 + 0x300)
146 #define RK3308_GLB_SRST_FST             0xb8
147 #define RK3308_SOFTRST_CON(x)           ((x) * 0x4 + 0x400)
148 #define RK3308_MODE_CON                 0xa0
149 #define RK3308_SDMMC_CON0               0x480
150 #define RK3308_SDMMC_CON1               0x484
151 #define RK3308_SDIO_CON0                0x488
152 #define RK3308_SDIO_CON1                0x48c
153 #define RK3308_EMMC_CON0                0x490
154 #define RK3308_EMMC_CON1                0x494
155
156 #define RK3328_PLL_CON(x)               RK2928_PLL_CON(x)
157 #define RK3328_CLKSEL_CON(x)            ((x) * 0x4 + 0x100)
158 #define RK3328_CLKGATE_CON(x)           ((x) * 0x4 + 0x200)
159 #define RK3328_GRFCLKSEL_CON(x)         ((x) * 0x4 + 0x100)
160 #define RK3328_GLB_SRST_FST             0x9c
161 #define RK3328_GLB_SRST_SND             0x98
162 #define RK3328_SOFTRST_CON(x)           ((x) * 0x4 + 0x300)
163 #define RK3328_MODE_CON                 0x80
164 #define RK3328_MISC_CON                 0x84
165 #define RK3328_SDMMC_CON0               0x380
166 #define RK3328_SDMMC_CON1               0x384
167 #define RK3328_SDIO_CON0                0x388
168 #define RK3328_SDIO_CON1                0x38c
169 #define RK3328_EMMC_CON0                0x390
170 #define RK3328_EMMC_CON1                0x394
171 #define RK3328_SDMMC_EXT_CON0           0x398
172 #define RK3328_SDMMC_EXT_CON1           0x39C
173
174 #define RK3368_PLL_CON(x)               RK2928_PLL_CON(x)
175 #define RK3368_CLKSEL_CON(x)            ((x) * 0x4 + 0x100)
176 #define RK3368_CLKGATE_CON(x)           ((x) * 0x4 + 0x200)
177 #define RK3368_GLB_SRST_FST             0x280
178 #define RK3368_GLB_SRST_SND             0x284
179 #define RK3368_SOFTRST_CON(x)           ((x) * 0x4 + 0x300)
180 #define RK3368_MISC_CON                 0x380
181 #define RK3368_SDMMC_CON0               0x400
182 #define RK3368_SDMMC_CON1               0x404
183 #define RK3368_SDIO0_CON0               0x408
184 #define RK3368_SDIO0_CON1               0x40c
185 #define RK3368_SDIO1_CON0               0x410
186 #define RK3368_SDIO1_CON1               0x414
187 #define RK3368_EMMC_CON0                0x418
188 #define RK3368_EMMC_CON1                0x41c
189
190 #define RK3399_PLL_CON(x)               RK2928_PLL_CON(x)
191 #define RK3399_CLKSEL_CON(x)            ((x) * 0x4 + 0x100)
192 #define RK3399_CLKGATE_CON(x)           ((x) * 0x4 + 0x300)
193 #define RK3399_SOFTRST_CON(x)           ((x) * 0x4 + 0x400)
194 #define RK3399_GLB_SRST_FST             0x500
195 #define RK3399_GLB_SRST_SND             0x504
196 #define RK3399_GLB_CNT_TH               0x508
197 #define RK3399_MISC_CON                 0x50c
198 #define RK3399_RST_CON                  0x510
199 #define RK3399_RST_ST                   0x514
200 #define RK3399_SDMMC_CON0               0x580
201 #define RK3399_SDMMC_CON1               0x584
202 #define RK3399_SDIO_CON0                0x588
203 #define RK3399_SDIO_CON1                0x58c
204
205 #define RK3399_PMU_PLL_CON(x)           RK2928_PLL_CON(x)
206 #define RK3399_PMU_CLKSEL_CON(x)        ((x) * 0x4 + 0x80)
207 #define RK3399_PMU_CLKGATE_CON(x)       ((x) * 0x4 + 0x100)
208 #define RK3399_PMU_SOFTRST_CON(x)       ((x) * 0x4 + 0x110)
209
210 #define RK3568_PLL_CON(x)               RK2928_PLL_CON(x)
211 #define RK3568_MODE_CON0                0xc0
212 #define RK3568_MISC_CON0                0xc4
213 #define RK3568_MISC_CON1                0xc8
214 #define RK3568_MISC_CON2                0xcc
215 #define RK3568_GLB_CNT_TH               0xd0
216 #define RK3568_GLB_SRST_FST             0xd4
217 #define RK3568_GLB_SRST_SND             0xd8
218 #define RK3568_GLB_RST_CON              0xdc
219 #define RK3568_GLB_RST_ST               0xe0
220 #define RK3568_CLKSEL_CON(x)            ((x) * 0x4 + 0x100)
221 #define RK3568_CLKGATE_CON(x)           ((x) * 0x4 + 0x300)
222 #define RK3568_SOFTRST_CON(x)           ((x) * 0x4 + 0x400)
223 #define RK3568_SDMMC0_CON0              0x580
224 #define RK3568_SDMMC0_CON1              0x584
225 #define RK3568_SDMMC1_CON0              0x588
226 #define RK3568_SDMMC1_CON1              0x58c
227 #define RK3568_SDMMC2_CON0              0x590
228 #define RK3568_SDMMC2_CON1              0x594
229 #define RK3568_EMMC_CON0                0x598
230 #define RK3568_EMMC_CON1                0x59c
231
232 #define RK3568_PMU_PLL_CON(x)           RK2928_PLL_CON(x)
233 #define RK3568_PMU_MODE_CON0            0x80
234 #define RK3568_PMU_CLKSEL_CON(x)        ((x) * 0x4 + 0x100)
235 #define RK3568_PMU_CLKGATE_CON(x)       ((x) * 0x4 + 0x180)
236 #define RK3568_PMU_SOFTRST_CON(x)       ((x) * 0x4 + 0x200)
237
238 #define RK3588_PHP_CRU_BASE             0x8000
239 #define RK3588_PMU_CRU_BASE             0x30000
240 #define RK3588_BIGCORE0_CRU_BASE        0x50000
241 #define RK3588_BIGCORE1_CRU_BASE        0x52000
242 #define RK3588_DSU_CRU_BASE             0x58000
243
244 #define RK3588_PLL_CON(x)               RK2928_PLL_CON(x)
245 #define RK3588_MODE_CON0                0x280
246 #define RK3588_B0_PLL_MODE_CON0         (RK3588_BIGCORE0_CRU_BASE + 0x280)
247 #define RK3588_B1_PLL_MODE_CON0         (RK3588_BIGCORE1_CRU_BASE + 0x280)
248 #define RK3588_LPLL_MODE_CON0           (RK3588_DSU_CRU_BASE + 0x280)
249 #define RK3588_CLKSEL_CON(x)            ((x) * 0x4 + 0x300)
250 #define RK3588_CLKGATE_CON(x)           ((x) * 0x4 + 0x800)
251 #define RK3588_SOFTRST_CON(x)           ((x) * 0x4 + 0xa00)
252 #define RK3588_GLB_CNT_TH               0xc00
253 #define RK3588_GLB_SRST_FST             0xc08
254 #define RK3588_GLB_SRST_SND             0xc0c
255 #define RK3588_GLB_RST_CON              0xc10
256 #define RK3588_GLB_RST_ST               0xc04
257 #define RK3588_SDIO_CON0                0xC24
258 #define RK3588_SDIO_CON1                0xC28
259 #define RK3588_SDMMC_CON0               0xC30
260 #define RK3588_SDMMC_CON1               0xC34
261
262 #define RK3588_PHP_CLKGATE_CON(x)       ((x) * 0x4 + RK3588_PHP_CRU_BASE + 0x800)
263 #define RK3588_PHP_SOFTRST_CON(x)       ((x) * 0x4 + RK3588_PHP_CRU_BASE + 0xa00)
264
265 #define RK3588_PMU_PLL_CON(x)           ((x) * 0x4 + RK3588_PHP_CRU_BASE)
266 #define RK3588_PMU_CLKSEL_CON(x)        ((x) * 0x4 + RK3588_PMU_CRU_BASE + 0x300)
267 #define RK3588_PMU_CLKGATE_CON(x)       ((x) * 0x4 + RK3588_PMU_CRU_BASE + 0x800)
268 #define RK3588_PMU_SOFTRST_CON(x)       ((x) * 0x4 + RK3588_PMU_CRU_BASE + 0xa00)
269
270 #define RK3588_B0_PLL_CON(x)            ((x) * 0x4 + RK3588_BIGCORE0_CRU_BASE)
271 #define RK3588_BIGCORE0_CLKSEL_CON(x)   ((x) * 0x4 + RK3588_BIGCORE0_CRU_BASE + 0x300)
272 #define RK3588_BIGCORE0_CLKGATE_CON(x)  ((x) * 0x4 + RK3588_BIGCORE0_CRU_BASE + 0x800)
273 #define RK3588_BIGCORE0_SOFTRST_CON(x)  ((x) * 0x4 + RK3588_BIGCORE0_CRU_BASE + 0xa00)
274 #define RK3588_B1_PLL_CON(x)            ((x) * 0x4 + RK3588_BIGCORE1_CRU_BASE)
275 #define RK3588_BIGCORE1_CLKSEL_CON(x)   ((x) * 0x4 + RK3588_BIGCORE1_CRU_BASE + 0x300)
276 #define RK3588_BIGCORE1_CLKGATE_CON(x)  ((x) * 0x4 + RK3588_BIGCORE1_CRU_BASE + 0x800)
277 #define RK3588_BIGCORE1_SOFTRST_CON(x)  ((x) * 0x4 + RK3588_BIGCORE1_CRU_BASE + 0xa00)
278 #define RK3588_LPLL_CON(x)              ((x) * 0x4 + RK3588_DSU_CRU_BASE)
279 #define RK3588_DSU_CLKSEL_CON(x)        ((x) * 0x4 + RK3588_DSU_CRU_BASE + 0x300)
280 #define RK3588_DSU_CLKGATE_CON(x)       ((x) * 0x4 + RK3588_DSU_CRU_BASE + 0x800)
281 #define RK3588_DSU_SOFTRST_CON(x)       ((x) * 0x4 + RK3588_DSU_CRU_BASE + 0xa00)
282
283 enum rockchip_pll_type {
284         pll_rk3036,
285         pll_rk3066,
286         pll_rk3328,
287         pll_rk3399,
288         pll_rk3588,
289         pll_rk3588_core,
290 };
291
292 #define RK3036_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1,      \
293                         _postdiv2, _dsmpd, _frac)               \
294 {                                                               \
295         .rate   = _rate##U,                                     \
296         .fbdiv = _fbdiv,                                        \
297         .postdiv1 = _postdiv1,                                  \
298         .refdiv = _refdiv,                                      \
299         .postdiv2 = _postdiv2,                                  \
300         .dsmpd = _dsmpd,                                        \
301         .frac = _frac,                                          \
302 }
303
304 #define RK3066_PLL_RATE(_rate, _nr, _nf, _no)   \
305 {                                               \
306         .rate   = _rate##U,                     \
307         .nr = _nr,                              \
308         .nf = _nf,                              \
309         .no = _no,                              \
310         .nb = ((_nf) < 2) ? 1 : (_nf) >> 1,     \
311 }
312
313 #define RK3066_PLL_RATE_NB(_rate, _nr, _nf, _no, _nb)           \
314 {                                                               \
315         .rate   = _rate##U,                                     \
316         .nr = _nr,                                              \
317         .nf = _nf,                                              \
318         .no = _no,                                              \
319         .nb = _nb,                                              \
320 }
321
322 #define RK3588_PLL_RATE(_rate, _p, _m, _s, _k)                  \
323 {                                                               \
324         .rate   = _rate##U,                                     \
325         .p = _p,                                                \
326         .m = _m,                                                \
327         .s = _s,                                                \
328         .k = _k,                                                \
329 }
330
331 /**
332  * struct rockchip_clk_provider - information about clock provider
333  * @reg_base: virtual address for the register base.
334  * @clk_data: holds clock related data like clk* and number of clocks.
335  * @cru_node: device-node of the clock-provider
336  * @grf: regmap of the general-register-files syscon
337  * @lock: maintains exclusion between callbacks for a given clock-provider.
338  */
339 struct rockchip_clk_provider {
340         void __iomem *reg_base;
341         struct clk_onecell_data clk_data;
342         struct device_node *cru_node;
343         struct regmap *grf;
344         spinlock_t lock;
345 };
346
347 struct rockchip_pll_rate_table {
348         unsigned long rate;
349         union {
350                 struct {
351                         /* for RK3066 */
352                         unsigned int nr;
353                         unsigned int nf;
354                         unsigned int no;
355                         unsigned int nb;
356                 };
357                 struct {
358                         /* for RK3036/RK3399 */
359                         unsigned int fbdiv;
360                         unsigned int postdiv1;
361                         unsigned int refdiv;
362                         unsigned int postdiv2;
363                         unsigned int dsmpd;
364                         unsigned int frac;
365                 };
366                 struct {
367                         /* for RK3588 */
368                         unsigned int m;
369                         unsigned int p;
370                         unsigned int s;
371                         unsigned int k;
372                 };
373         };
374 };
375
376 /**
377  * struct rockchip_pll_clock - information about pll clock
378  * @id: platform specific id of the clock.
379  * @name: name of this pll clock.
380  * @parent_names: name of the parent clock.
381  * @num_parents: number of parents
382  * @flags: optional flags for basic clock.
383  * @con_offset: offset of the register for configuring the PLL.
384  * @mode_offset: offset of the register for configuring the PLL-mode.
385  * @mode_shift: offset inside the mode-register for the mode of this pll.
386  * @lock_shift: offset inside the lock register for the lock status.
387  * @type: Type of PLL to be registered.
388  * @pll_flags: hardware-specific flags
389  * @rate_table: Table of usable pll rates
390  *
391  * Flags:
392  * ROCKCHIP_PLL_SYNC_RATE - check rate parameters to match against the
393  *      rate_table parameters and ajust them if necessary.
394  */
395 struct rockchip_pll_clock {
396         unsigned int            id;
397         const char              *name;
398         const char              *const *parent_names;
399         u8                      num_parents;
400         unsigned long           flags;
401         int                     con_offset;
402         int                     mode_offset;
403         int                     mode_shift;
404         int                     lock_shift;
405         enum rockchip_pll_type  type;
406         u8                      pll_flags;
407         struct rockchip_pll_rate_table *rate_table;
408 };
409
410 #define ROCKCHIP_PLL_SYNC_RATE          BIT(0)
411
412 #define PLL(_type, _id, _name, _pnames, _flags, _con, _mode, _mshift,   \
413                 _lshift, _pflags, _rtable)                              \
414         {                                                               \
415                 .id             = _id,                                  \
416                 .type           = _type,                                \
417                 .name           = _name,                                \
418                 .parent_names   = _pnames,                              \
419                 .num_parents    = ARRAY_SIZE(_pnames),                  \
420                 .flags          = CLK_GET_RATE_NOCACHE | _flags,        \
421                 .con_offset     = _con,                                 \
422                 .mode_offset    = _mode,                                \
423                 .mode_shift     = _mshift,                              \
424                 .lock_shift     = _lshift,                              \
425                 .pll_flags      = _pflags,                              \
426                 .rate_table     = _rtable,                              \
427         }
428
429 struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
430                 enum rockchip_pll_type pll_type,
431                 const char *name, const char *const *parent_names,
432                 u8 num_parents, int con_offset, int grf_lock_offset,
433                 int lock_shift, int mode_offset, int mode_shift,
434                 struct rockchip_pll_rate_table *rate_table,
435                 unsigned long flags, u8 clk_pll_flags);
436
437 struct rockchip_cpuclk_clksel {
438         int reg;
439         u32 val;
440 };
441
442 #define ROCKCHIP_CPUCLK_NUM_DIVIDERS    6
443 #define ROCKCHIP_CPUCLK_MAX_CORES       4
444 struct rockchip_cpuclk_rate_table {
445         unsigned long prate;
446         struct rockchip_cpuclk_clksel divs[ROCKCHIP_CPUCLK_NUM_DIVIDERS];
447         struct rockchip_cpuclk_clksel pre_muxs[ROCKCHIP_CPUCLK_NUM_DIVIDERS];
448         struct rockchip_cpuclk_clksel post_muxs[ROCKCHIP_CPUCLK_NUM_DIVIDERS];
449 };
450
451 /**
452  * struct rockchip_cpuclk_reg_data - register offsets and masks of the cpuclock
453  * @core_reg[]: register offset of the cores setting register
454  * @div_core_shift[]:   cores divider offset used to divide the pll value
455  * @div_core_mask[]:    cores divider mask
456  * @num_cores:  number of cpu cores
457  * @mux_core_reg:       register offset of the cores select parent
458  * @mux_core_alt:       mux value to select alternate parent
459  * @mux_core_main:      mux value to select main parent of core
460  * @mux_core_shift:     offset of the core multiplexer
461  * @mux_core_mask:      core multiplexer mask
462  */
463 struct rockchip_cpuclk_reg_data {
464         int     core_reg[ROCKCHIP_CPUCLK_MAX_CORES];
465         u8      div_core_shift[ROCKCHIP_CPUCLK_MAX_CORES];
466         u32     div_core_mask[ROCKCHIP_CPUCLK_MAX_CORES];
467         int     num_cores;
468         int     mux_core_reg;
469         u8      mux_core_alt;
470         u8      mux_core_main;
471         u8      mux_core_shift;
472         u32     mux_core_mask;
473 };
474
475 struct clk *rockchip_clk_register_cpuclk(const char *name,
476                         const char *const *parent_names, u8 num_parents,
477                         const struct rockchip_cpuclk_reg_data *reg_data,
478                         const struct rockchip_cpuclk_rate_table *rates,
479                         int nrates, void __iomem *reg_base, spinlock_t *lock);
480
481 struct clk *rockchip_clk_register_mmc(const char *name,
482                                 const char *const *parent_names, u8 num_parents,
483                                 void __iomem *reg, int shift);
484
485 /*
486  * DDRCLK flags, including method of setting the rate
487  * ROCKCHIP_DDRCLK_SIP: use SIP call to bl31 to change ddrclk rate.
488  */
489 #define ROCKCHIP_DDRCLK_SIP             BIT(0)
490
491 struct clk *rockchip_clk_register_ddrclk(const char *name, int flags,
492                                          const char *const *parent_names,
493                                          u8 num_parents, int mux_offset,
494                                          int mux_shift, int mux_width,
495                                          int div_shift, int div_width,
496                                          int ddr_flags, void __iomem *reg_base,
497                                          spinlock_t *lock);
498
499 #define ROCKCHIP_INVERTER_HIWORD_MASK   BIT(0)
500
501 struct clk *rockchip_clk_register_inverter(const char *name,
502                                 const char *const *parent_names, u8 num_parents,
503                                 void __iomem *reg, int shift, int flags,
504                                 spinlock_t *lock);
505
506 struct clk *rockchip_clk_register_muxgrf(const char *name,
507                                 const char *const *parent_names, u8 num_parents,
508                                 int flags, struct regmap *grf, int reg,
509                                 int shift, int width, int mux_flags);
510
511 #define PNAME(x) static const char *const x[] __initconst
512
513 enum rockchip_clk_branch_type {
514         branch_composite,
515         branch_mux,
516         branch_muxgrf,
517         branch_divider,
518         branch_fraction_divider,
519         branch_gate,
520         branch_mmc,
521         branch_inverter,
522         branch_factor,
523         branch_ddrclk,
524         branch_half_divider,
525 };
526
527 struct rockchip_clk_branch {
528         unsigned int                    id;
529         enum rockchip_clk_branch_type   branch_type;
530         const char                      *name;
531         const char                      *const *parent_names;
532         u8                              num_parents;
533         unsigned long                   flags;
534         int                             muxdiv_offset;
535         u8                              mux_shift;
536         u8                              mux_width;
537         u8                              mux_flags;
538         u32                             *mux_table;
539         int                             div_offset;
540         u8                              div_shift;
541         u8                              div_width;
542         u8                              div_flags;
543         struct clk_div_table            *div_table;
544         int                             gate_offset;
545         u8                              gate_shift;
546         u8                              gate_flags;
547         struct rockchip_clk_branch      *child;
548 };
549
550 #define COMPOSITE(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw,\
551                   df, go, gs, gf)                               \
552         {                                                       \
553                 .id             = _id,                          \
554                 .branch_type    = branch_composite,             \
555                 .name           = cname,                        \
556                 .parent_names   = pnames,                       \
557                 .num_parents    = ARRAY_SIZE(pnames),           \
558                 .flags          = f,                            \
559                 .muxdiv_offset  = mo,                           \
560                 .mux_shift      = ms,                           \
561                 .mux_width      = mw,                           \
562                 .mux_flags      = mf,                           \
563                 .div_shift      = ds,                           \
564                 .div_width      = dw,                           \
565                 .div_flags      = df,                           \
566                 .gate_offset    = go,                           \
567                 .gate_shift     = gs,                           \
568                 .gate_flags     = gf,                           \
569         }
570
571 #define COMPOSITE_DIV_OFFSET(_id, cname, pnames, f, mo, ms, mw, \
572                              mf, do, ds, dw, df, go, gs, gf)    \
573         {                                                       \
574                 .id             = _id,                          \
575                 .branch_type    = branch_composite,             \
576                 .name           = cname,                        \
577                 .parent_names   = pnames,                       \
578                 .num_parents    = ARRAY_SIZE(pnames),           \
579                 .flags          = f,                            \
580                 .muxdiv_offset  = mo,                           \
581                 .mux_shift      = ms,                           \
582                 .mux_width      = mw,                           \
583                 .mux_flags      = mf,                           \
584                 .div_offset     = do,                           \
585                 .div_shift      = ds,                           \
586                 .div_width      = dw,                           \
587                 .div_flags      = df,                           \
588                 .gate_offset    = go,                           \
589                 .gate_shift     = gs,                           \
590                 .gate_flags     = gf,                           \
591         }
592
593 #define COMPOSITE_NOMUX(_id, cname, pname, f, mo, ds, dw, df,   \
594                         go, gs, gf)                             \
595         {                                                       \
596                 .id             = _id,                          \
597                 .branch_type    = branch_composite,             \
598                 .name           = cname,                        \
599                 .parent_names   = (const char *[]){ pname },    \
600                 .num_parents    = 1,                            \
601                 .flags          = f,                            \
602                 .muxdiv_offset  = mo,                           \
603                 .div_shift      = ds,                           \
604                 .div_width      = dw,                           \
605                 .div_flags      = df,                           \
606                 .gate_offset    = go,                           \
607                 .gate_shift     = gs,                           \
608                 .gate_flags     = gf,                           \
609         }
610
611 #define COMPOSITE_NOMUX_DIVTBL(_id, cname, pname, f, mo, ds, dw,\
612                                df, dt, go, gs, gf)              \
613         {                                                       \
614                 .id             = _id,                          \
615                 .branch_type    = branch_composite,             \
616                 .name           = cname,                        \
617                 .parent_names   = (const char *[]){ pname },    \
618                 .num_parents    = 1,                            \
619                 .flags          = f,                            \
620                 .muxdiv_offset  = mo,                           \
621                 .div_shift      = ds,                           \
622                 .div_width      = dw,                           \
623                 .div_flags      = df,                           \
624                 .div_table      = dt,                           \
625                 .gate_offset    = go,                           \
626                 .gate_shift     = gs,                           \
627                 .gate_flags     = gf,                           \
628         }
629
630 #define COMPOSITE_NODIV(_id, cname, pnames, f, mo, ms, mw, mf,  \
631                         go, gs, gf)                             \
632         {                                                       \
633                 .id             = _id,                          \
634                 .branch_type    = branch_composite,             \
635                 .name           = cname,                        \
636                 .parent_names   = pnames,                       \
637                 .num_parents    = ARRAY_SIZE(pnames),           \
638                 .flags          = f,                            \
639                 .muxdiv_offset  = mo,                           \
640                 .mux_shift      = ms,                           \
641                 .mux_width      = mw,                           \
642                 .mux_flags      = mf,                           \
643                 .gate_offset    = go,                           \
644                 .gate_shift     = gs,                           \
645                 .gate_flags     = gf,                           \
646         }
647
648 #define COMPOSITE_NOGATE(_id, cname, pnames, f, mo, ms, mw, mf, \
649                          ds, dw, df)                            \
650         {                                                       \
651                 .id             = _id,                          \
652                 .branch_type    = branch_composite,             \
653                 .name           = cname,                        \
654                 .parent_names   = pnames,                       \
655                 .num_parents    = ARRAY_SIZE(pnames),           \
656                 .flags          = f,                            \
657                 .muxdiv_offset  = mo,                           \
658                 .mux_shift      = ms,                           \
659                 .mux_width      = mw,                           \
660                 .mux_flags      = mf,                           \
661                 .div_shift      = ds,                           \
662                 .div_width      = dw,                           \
663                 .div_flags      = df,                           \
664                 .gate_offset    = -1,                           \
665         }
666
667 #define COMPOSITE_NOGATE_DIVTBL(_id, cname, pnames, f, mo, ms,  \
668                                 mw, mf, ds, dw, df, dt)         \
669         {                                                       \
670                 .id             = _id,                          \
671                 .branch_type    = branch_composite,             \
672                 .name           = cname,                        \
673                 .parent_names   = pnames,                       \
674                 .num_parents    = ARRAY_SIZE(pnames),           \
675                 .flags          = f,                            \
676                 .muxdiv_offset  = mo,                           \
677                 .mux_shift      = ms,                           \
678                 .mux_width      = mw,                           \
679                 .mux_flags      = mf,                           \
680                 .div_shift      = ds,                           \
681                 .div_width      = dw,                           \
682                 .div_flags      = df,                           \
683                 .div_table      = dt,                           \
684                 .gate_offset    = -1,                           \
685         }
686
687 #define COMPOSITE_FRAC(_id, cname, pname, f, mo, df, go, gs, gf)\
688         {                                                       \
689                 .id             = _id,                          \
690                 .branch_type    = branch_fraction_divider,      \
691                 .name           = cname,                        \
692                 .parent_names   = (const char *[]){ pname },    \
693                 .num_parents    = 1,                            \
694                 .flags          = f,                            \
695                 .muxdiv_offset  = mo,                           \
696                 .div_shift      = 16,                           \
697                 .div_width      = 16,                           \
698                 .div_flags      = df,                           \
699                 .gate_offset    = go,                           \
700                 .gate_shift     = gs,                           \
701                 .gate_flags     = gf,                           \
702         }
703
704 #define COMPOSITE_FRACMUX(_id, cname, pname, f, mo, df, go, gs, gf, ch) \
705         {                                                       \
706                 .id             = _id,                          \
707                 .branch_type    = branch_fraction_divider,      \
708                 .name           = cname,                        \
709                 .parent_names   = (const char *[]){ pname },    \
710                 .num_parents    = 1,                            \
711                 .flags          = f,                            \
712                 .muxdiv_offset  = mo,                           \
713                 .div_shift      = 16,                           \
714                 .div_width      = 16,                           \
715                 .div_flags      = df,                           \
716                 .gate_offset    = go,                           \
717                 .gate_shift     = gs,                           \
718                 .gate_flags     = gf,                           \
719                 .child          = ch,                           \
720         }
721
722 #define COMPOSITE_FRACMUX_NOGATE(_id, cname, pname, f, mo, df, ch) \
723         {                                                       \
724                 .id             = _id,                          \
725                 .branch_type    = branch_fraction_divider,      \
726                 .name           = cname,                        \
727                 .parent_names   = (const char *[]){ pname },    \
728                 .num_parents    = 1,                            \
729                 .flags          = f,                            \
730                 .muxdiv_offset  = mo,                           \
731                 .div_shift      = 16,                           \
732                 .div_width      = 16,                           \
733                 .div_flags      = df,                           \
734                 .gate_offset    = -1,                           \
735                 .child          = ch,                           \
736         }
737
738 #define COMPOSITE_DDRCLK(_id, cname, pnames, f, mo, ms, mw,     \
739                          ds, dw, df)                            \
740         {                                                       \
741                 .id             = _id,                          \
742                 .branch_type    = branch_ddrclk,                \
743                 .name           = cname,                        \
744                 .parent_names   = pnames,                       \
745                 .num_parents    = ARRAY_SIZE(pnames),           \
746                 .flags          = f,                            \
747                 .muxdiv_offset  = mo,                           \
748                 .mux_shift      = ms,                           \
749                 .mux_width      = mw,                           \
750                 .div_shift      = ds,                           \
751                 .div_width      = dw,                           \
752                 .div_flags      = df,                           \
753                 .gate_offset    = -1,                           \
754         }
755
756 #define MUX(_id, cname, pnames, f, o, s, w, mf)                 \
757         {                                                       \
758                 .id             = _id,                          \
759                 .branch_type    = branch_mux,                   \
760                 .name           = cname,                        \
761                 .parent_names   = pnames,                       \
762                 .num_parents    = ARRAY_SIZE(pnames),           \
763                 .flags          = f,                            \
764                 .muxdiv_offset  = o,                            \
765                 .mux_shift      = s,                            \
766                 .mux_width      = w,                            \
767                 .mux_flags      = mf,                           \
768                 .gate_offset    = -1,                           \
769         }
770
771 #define MUXTBL(_id, cname, pnames, f, o, s, w, mf, mt)          \
772         {                                                       \
773                 .id             = _id,                          \
774                 .branch_type    = branch_mux,                   \
775                 .name           = cname,                        \
776                 .parent_names   = pnames,                       \
777                 .num_parents    = ARRAY_SIZE(pnames),           \
778                 .flags          = f,                            \
779                 .muxdiv_offset  = o,                            \
780                 .mux_shift      = s,                            \
781                 .mux_width      = w,                            \
782                 .mux_flags      = mf,                           \
783                 .gate_offset    = -1,                           \
784                 .mux_table      = mt,                           \
785         }
786
787 #define MUXGRF(_id, cname, pnames, f, o, s, w, mf)              \
788         {                                                       \
789                 .id             = _id,                          \
790                 .branch_type    = branch_muxgrf,                \
791                 .name           = cname,                        \
792                 .parent_names   = pnames,                       \
793                 .num_parents    = ARRAY_SIZE(pnames),           \
794                 .flags          = f,                            \
795                 .muxdiv_offset  = o,                            \
796                 .mux_shift      = s,                            \
797                 .mux_width      = w,                            \
798                 .mux_flags      = mf,                           \
799                 .gate_offset    = -1,                           \
800         }
801
802 #define DIV(_id, cname, pname, f, o, s, w, df)                  \
803         {                                                       \
804                 .id             = _id,                          \
805                 .branch_type    = branch_divider,               \
806                 .name           = cname,                        \
807                 .parent_names   = (const char *[]){ pname },    \
808                 .num_parents    = 1,                            \
809                 .flags          = f,                            \
810                 .muxdiv_offset  = o,                            \
811                 .div_shift      = s,                            \
812                 .div_width      = w,                            \
813                 .div_flags      = df,                           \
814                 .gate_offset    = -1,                           \
815         }
816
817 #define DIVTBL(_id, cname, pname, f, o, s, w, df, dt)           \
818         {                                                       \
819                 .id             = _id,                          \
820                 .branch_type    = branch_divider,               \
821                 .name           = cname,                        \
822                 .parent_names   = (const char *[]){ pname },    \
823                 .num_parents    = 1,                            \
824                 .flags          = f,                            \
825                 .muxdiv_offset  = o,                            \
826                 .div_shift      = s,                            \
827                 .div_width      = w,                            \
828                 .div_flags      = df,                           \
829                 .div_table      = dt,                           \
830         }
831
832 #define GATE(_id, cname, pname, f, o, b, gf)                    \
833         {                                                       \
834                 .id             = _id,                          \
835                 .branch_type    = branch_gate,                  \
836                 .name           = cname,                        \
837                 .parent_names   = (const char *[]){ pname },    \
838                 .num_parents    = 1,                            \
839                 .flags          = f,                            \
840                 .gate_offset    = o,                            \
841                 .gate_shift     = b,                            \
842                 .gate_flags     = gf,                           \
843         }
844
845 #define MMC(_id, cname, pname, offset, shift)                   \
846         {                                                       \
847                 .id             = _id,                          \
848                 .branch_type    = branch_mmc,                   \
849                 .name           = cname,                        \
850                 .parent_names   = (const char *[]){ pname },    \
851                 .num_parents    = 1,                            \
852                 .muxdiv_offset  = offset,                       \
853                 .div_shift      = shift,                        \
854         }
855
856 #define INVERTER(_id, cname, pname, io, is, if)                 \
857         {                                                       \
858                 .id             = _id,                          \
859                 .branch_type    = branch_inverter,              \
860                 .name           = cname,                        \
861                 .parent_names   = (const char *[]){ pname },    \
862                 .num_parents    = 1,                            \
863                 .muxdiv_offset  = io,                           \
864                 .div_shift      = is,                           \
865                 .div_flags      = if,                           \
866         }
867
868 #define FACTOR(_id, cname, pname,  f, fm, fd)                   \
869         {                                                       \
870                 .id             = _id,                          \
871                 .branch_type    = branch_factor,                \
872                 .name           = cname,                        \
873                 .parent_names   = (const char *[]){ pname },    \
874                 .num_parents    = 1,                            \
875                 .flags          = f,                            \
876                 .div_shift      = fm,                           \
877                 .div_width      = fd,                           \
878         }
879
880 #define FACTOR_GATE(_id, cname, pname,  f, fm, fd, go, gb, gf)  \
881         {                                                       \
882                 .id             = _id,                          \
883                 .branch_type    = branch_factor,                \
884                 .name           = cname,                        \
885                 .parent_names   = (const char *[]){ pname },    \
886                 .num_parents    = 1,                            \
887                 .flags          = f,                            \
888                 .div_shift      = fm,                           \
889                 .div_width      = fd,                           \
890                 .gate_offset    = go,                           \
891                 .gate_shift     = gb,                           \
892                 .gate_flags     = gf,                           \
893         }
894
895 #define COMPOSITE_HALFDIV(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw,\
896                           df, go, gs, gf)                               \
897         {                                                       \
898                 .id             = _id,                          \
899                 .branch_type    = branch_half_divider,          \
900                 .name           = cname,                        \
901                 .parent_names   = pnames,                       \
902                 .num_parents    = ARRAY_SIZE(pnames),           \
903                 .flags          = f,                            \
904                 .muxdiv_offset  = mo,                           \
905                 .mux_shift      = ms,                           \
906                 .mux_width      = mw,                           \
907                 .mux_flags      = mf,                           \
908                 .div_shift      = ds,                           \
909                 .div_width      = dw,                           \
910                 .div_flags      = df,                           \
911                 .gate_offset    = go,                           \
912                 .gate_shift     = gs,                           \
913                 .gate_flags     = gf,                           \
914         }
915
916 #define COMPOSITE_NOGATE_HALFDIV(_id, cname, pnames, f, mo, ms, mw, mf, \
917                                  ds, dw, df)                            \
918         {                                                       \
919                 .id             = _id,                          \
920                 .branch_type    = branch_half_divider,          \
921                 .name           = cname,                        \
922                 .parent_names   = pnames,                       \
923                 .num_parents    = ARRAY_SIZE(pnames),           \
924                 .flags          = f,                            \
925                 .muxdiv_offset  = mo,                           \
926                 .mux_shift      = ms,                           \
927                 .mux_width      = mw,                           \
928                 .mux_flags      = mf,                           \
929                 .div_shift      = ds,                           \
930                 .div_width      = dw,                           \
931                 .div_flags      = df,                           \
932                 .gate_offset    = -1,                           \
933         }
934
935 #define COMPOSITE_NOMUX_HALFDIV(_id, cname, pname, f, mo, ds, dw, df,   \
936                         go, gs, gf)                             \
937         {                                                       \
938                 .id             = _id,                          \
939                 .branch_type    = branch_half_divider,          \
940                 .name           = cname,                        \
941                 .parent_names   = (const char *[]){ pname },    \
942                 .num_parents    = 1,                            \
943                 .flags          = f,                            \
944                 .muxdiv_offset  = mo,                           \
945                 .div_shift      = ds,                           \
946                 .div_width      = dw,                           \
947                 .div_flags      = df,                           \
948                 .gate_offset    = go,                           \
949                 .gate_shift     = gs,                           \
950                 .gate_flags     = gf,                           \
951         }
952
953 #define DIV_HALF(_id, cname, pname, f, o, s, w, df)                     \
954         {                                                       \
955                 .id             = _id,                          \
956                 .branch_type    = branch_half_divider,          \
957                 .name           = cname,                        \
958                 .parent_names   = (const char *[]){ pname },    \
959                 .num_parents    = 1,                            \
960                 .flags          = f,                            \
961                 .muxdiv_offset  = o,                            \
962                 .div_shift      = s,                            \
963                 .div_width      = w,                            \
964                 .div_flags      = df,                           \
965                 .gate_offset    = -1,                           \
966         }
967
968 /* SGRF clocks are only accessible from secure mode, so not controllable */
969 #define SGRF_GATE(_id, cname, pname)                            \
970                 FACTOR(_id, cname, pname, 0, 1, 1)
971
972 struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np,
973                         void __iomem *base, unsigned long nr_clks);
974 void rockchip_clk_of_add_provider(struct device_node *np,
975                                 struct rockchip_clk_provider *ctx);
976 void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
977                                     struct rockchip_clk_branch *list,
978                                     unsigned int nr_clk);
979 void rockchip_clk_register_plls(struct rockchip_clk_provider *ctx,
980                                 struct rockchip_pll_clock *pll_list,
981                                 unsigned int nr_pll, int grf_lock_offset);
982 void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx,
983                         unsigned int lookup_id, const char *name,
984                         const char *const *parent_names, u8 num_parents,
985                         const struct rockchip_cpuclk_reg_data *reg_data,
986                         const struct rockchip_cpuclk_rate_table *rates,
987                         int nrates);
988 void rockchip_clk_protect_critical(const char *const clocks[], int nclocks);
989 void rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx,
990                                         unsigned int reg, void (*cb)(void));
991
992 #define ROCKCHIP_SOFTRST_HIWORD_MASK    BIT(0)
993
994 struct clk *rockchip_clk_register_halfdiv(const char *name,
995                                           const char *const *parent_names,
996                                           u8 num_parents, void __iomem *base,
997                                           int muxdiv_offset, u8 mux_shift,
998                                           u8 mux_width, u8 mux_flags,
999                                           u8 div_shift, u8 div_width,
1000                                           u8 div_flags, int gate_offset,
1001                                           u8 gate_shift, u8 gate_flags,
1002                                           unsigned long flags,
1003                                           spinlock_t *lock);
1004
1005 #ifdef CONFIG_RESET_CONTROLLER
1006 void rockchip_register_softrst_lut(struct device_node *np,
1007                                    const int *lookup_table,
1008                                    unsigned int num_regs,
1009                                    void __iomem *base, u8 flags);
1010 #else
1011 static inline void rockchip_register_softrst_lut(struct device_node *np,
1012                                    const int *lookup_table,
1013                                    unsigned int num_regs,
1014                                    void __iomem *base, u8 flags)
1015 {
1016 }
1017 #endif
1018
1019 static inline void rockchip_register_softrst(struct device_node *np,
1020                                              unsigned int num_regs,
1021                                              void __iomem *base, u8 flags)
1022 {
1023         return rockchip_register_softrst_lut(np, NULL, num_regs, base, flags);
1024 }
1025
1026 void rk3588_rst_init(struct device_node *np, void __iomem *reg_base);
1027
1028 #endif