]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/clk/rockchip/clk.h
Merge branch 'hinic-BugFixes'
[linux.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 RK2928_PLL_CON(x)               ((x) * 0x4)
83 #define RK2928_MODE_CON         0x40
84 #define RK2928_CLKSEL_CON(x)    ((x) * 0x4 + 0x44)
85 #define RK2928_CLKGATE_CON(x)   ((x) * 0x4 + 0xd0)
86 #define RK2928_GLB_SRST_FST             0x100
87 #define RK2928_GLB_SRST_SND             0x104
88 #define RK2928_SOFTRST_CON(x)   ((x) * 0x4 + 0x110)
89 #define RK2928_MISC_CON         0x134
90
91 #define RK3036_SDMMC_CON0               0x144
92 #define RK3036_SDMMC_CON1               0x148
93 #define RK3036_SDIO_CON0                0x14c
94 #define RK3036_SDIO_CON1                0x150
95 #define RK3036_EMMC_CON0                0x154
96 #define RK3036_EMMC_CON1                0x158
97
98 #define RK3228_GLB_SRST_FST             0x1f0
99 #define RK3228_GLB_SRST_SND             0x1f4
100 #define RK3228_SDMMC_CON0               0x1c0
101 #define RK3228_SDMMC_CON1               0x1c4
102 #define RK3228_SDIO_CON0                0x1c8
103 #define RK3228_SDIO_CON1                0x1cc
104 #define RK3228_EMMC_CON0                0x1d8
105 #define RK3228_EMMC_CON1                0x1dc
106
107 #define RK3288_PLL_CON(x)               RK2928_PLL_CON(x)
108 #define RK3288_MODE_CON                 0x50
109 #define RK3288_CLKSEL_CON(x)            ((x) * 0x4 + 0x60)
110 #define RK3288_CLKGATE_CON(x)           ((x) * 0x4 + 0x160)
111 #define RK3288_GLB_SRST_FST             0x1b0
112 #define RK3288_GLB_SRST_SND             0x1b4
113 #define RK3288_SOFTRST_CON(x)           ((x) * 0x4 + 0x1b8)
114 #define RK3288_MISC_CON                 0x1e8
115 #define RK3288_SDMMC_CON0               0x200
116 #define RK3288_SDMMC_CON1               0x204
117 #define RK3288_SDIO0_CON0               0x208
118 #define RK3288_SDIO0_CON1               0x20c
119 #define RK3288_SDIO1_CON0               0x210
120 #define RK3288_SDIO1_CON1               0x214
121 #define RK3288_EMMC_CON0                0x218
122 #define RK3288_EMMC_CON1                0x21c
123
124 #define RK3308_PLL_CON(x)               RK2928_PLL_CON(x)
125 #define RK3308_CLKSEL_CON(x)            ((x) * 0x4 + 0x100)
126 #define RK3308_CLKGATE_CON(x)           ((x) * 0x4 + 0x300)
127 #define RK3308_GLB_SRST_FST             0xb8
128 #define RK3308_SOFTRST_CON(x)           ((x) * 0x4 + 0x400)
129 #define RK3308_MODE_CON                 0xa0
130 #define RK3308_SDMMC_CON0               0x480
131 #define RK3308_SDMMC_CON1               0x484
132 #define RK3308_SDIO_CON0                0x488
133 #define RK3308_SDIO_CON1                0x48c
134 #define RK3308_EMMC_CON0                0x490
135 #define RK3308_EMMC_CON1                0x494
136
137 #define RK3328_PLL_CON(x)               RK2928_PLL_CON(x)
138 #define RK3328_CLKSEL_CON(x)            ((x) * 0x4 + 0x100)
139 #define RK3328_CLKGATE_CON(x)           ((x) * 0x4 + 0x200)
140 #define RK3328_GRFCLKSEL_CON(x)         ((x) * 0x4 + 0x100)
141 #define RK3328_GLB_SRST_FST             0x9c
142 #define RK3328_GLB_SRST_SND             0x98
143 #define RK3328_SOFTRST_CON(x)           ((x) * 0x4 + 0x300)
144 #define RK3328_MODE_CON                 0x80
145 #define RK3328_MISC_CON                 0x84
146 #define RK3328_SDMMC_CON0               0x380
147 #define RK3328_SDMMC_CON1               0x384
148 #define RK3328_SDIO_CON0                0x388
149 #define RK3328_SDIO_CON1                0x38c
150 #define RK3328_EMMC_CON0                0x390
151 #define RK3328_EMMC_CON1                0x394
152 #define RK3328_SDMMC_EXT_CON0           0x398
153 #define RK3328_SDMMC_EXT_CON1           0x39C
154
155 #define RK3368_PLL_CON(x)               RK2928_PLL_CON(x)
156 #define RK3368_CLKSEL_CON(x)            ((x) * 0x4 + 0x100)
157 #define RK3368_CLKGATE_CON(x)           ((x) * 0x4 + 0x200)
158 #define RK3368_GLB_SRST_FST             0x280
159 #define RK3368_GLB_SRST_SND             0x284
160 #define RK3368_SOFTRST_CON(x)           ((x) * 0x4 + 0x300)
161 #define RK3368_MISC_CON                 0x380
162 #define RK3368_SDMMC_CON0               0x400
163 #define RK3368_SDMMC_CON1               0x404
164 #define RK3368_SDIO0_CON0               0x408
165 #define RK3368_SDIO0_CON1               0x40c
166 #define RK3368_SDIO1_CON0               0x410
167 #define RK3368_SDIO1_CON1               0x414
168 #define RK3368_EMMC_CON0                0x418
169 #define RK3368_EMMC_CON1                0x41c
170
171 #define RK3399_PLL_CON(x)               RK2928_PLL_CON(x)
172 #define RK3399_CLKSEL_CON(x)            ((x) * 0x4 + 0x100)
173 #define RK3399_CLKGATE_CON(x)           ((x) * 0x4 + 0x300)
174 #define RK3399_SOFTRST_CON(x)           ((x) * 0x4 + 0x400)
175 #define RK3399_GLB_SRST_FST             0x500
176 #define RK3399_GLB_SRST_SND             0x504
177 #define RK3399_GLB_CNT_TH               0x508
178 #define RK3399_MISC_CON                 0x50c
179 #define RK3399_RST_CON                  0x510
180 #define RK3399_RST_ST                   0x514
181 #define RK3399_SDMMC_CON0               0x580
182 #define RK3399_SDMMC_CON1               0x584
183 #define RK3399_SDIO_CON0                0x588
184 #define RK3399_SDIO_CON1                0x58c
185
186 #define RK3399_PMU_PLL_CON(x)           RK2928_PLL_CON(x)
187 #define RK3399_PMU_CLKSEL_CON(x)        ((x) * 0x4 + 0x80)
188 #define RK3399_PMU_CLKGATE_CON(x)       ((x) * 0x4 + 0x100)
189 #define RK3399_PMU_SOFTRST_CON(x)       ((x) * 0x4 + 0x110)
190
191 enum rockchip_pll_type {
192         pll_rk3036,
193         pll_rk3066,
194         pll_rk3328,
195         pll_rk3399,
196 };
197
198 #define RK3036_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1,      \
199                         _postdiv2, _dsmpd, _frac)               \
200 {                                                               \
201         .rate   = _rate##U,                                     \
202         .fbdiv = _fbdiv,                                        \
203         .postdiv1 = _postdiv1,                                  \
204         .refdiv = _refdiv,                                      \
205         .postdiv2 = _postdiv2,                                  \
206         .dsmpd = _dsmpd,                                        \
207         .frac = _frac,                                          \
208 }
209
210 #define RK3066_PLL_RATE(_rate, _nr, _nf, _no)   \
211 {                                               \
212         .rate   = _rate##U,                     \
213         .nr = _nr,                              \
214         .nf = _nf,                              \
215         .no = _no,                              \
216         .nb = ((_nf) < 2) ? 1 : (_nf) >> 1,     \
217 }
218
219 #define RK3066_PLL_RATE_NB(_rate, _nr, _nf, _no, _nb)           \
220 {                                                               \
221         .rate   = _rate##U,                                     \
222         .nr = _nr,                                              \
223         .nf = _nf,                                              \
224         .no = _no,                                              \
225         .nb = _nb,                                              \
226 }
227
228 /**
229  * struct rockchip_clk_provider - information about clock provider
230  * @reg_base: virtual address for the register base.
231  * @clk_data: holds clock related data like clk* and number of clocks.
232  * @cru_node: device-node of the clock-provider
233  * @grf: regmap of the general-register-files syscon
234  * @lock: maintains exclusion between callbacks for a given clock-provider.
235  */
236 struct rockchip_clk_provider {
237         void __iomem *reg_base;
238         struct clk_onecell_data clk_data;
239         struct device_node *cru_node;
240         struct regmap *grf;
241         spinlock_t lock;
242 };
243
244 struct rockchip_pll_rate_table {
245         unsigned long rate;
246         unsigned int nr;
247         unsigned int nf;
248         unsigned int no;
249         unsigned int nb;
250         /* for RK3036/RK3399 */
251         unsigned int fbdiv;
252         unsigned int postdiv1;
253         unsigned int refdiv;
254         unsigned int postdiv2;
255         unsigned int dsmpd;
256         unsigned int frac;
257 };
258
259 /**
260  * struct rockchip_pll_clock - information about pll clock
261  * @id: platform specific id of the clock.
262  * @name: name of this pll clock.
263  * @parent_names: name of the parent clock.
264  * @num_parents: number of parents
265  * @flags: optional flags for basic clock.
266  * @con_offset: offset of the register for configuring the PLL.
267  * @mode_offset: offset of the register for configuring the PLL-mode.
268  * @mode_shift: offset inside the mode-register for the mode of this pll.
269  * @lock_shift: offset inside the lock register for the lock status.
270  * @type: Type of PLL to be registered.
271  * @pll_flags: hardware-specific flags
272  * @rate_table: Table of usable pll rates
273  *
274  * Flags:
275  * ROCKCHIP_PLL_SYNC_RATE - check rate parameters to match against the
276  *      rate_table parameters and ajust them if necessary.
277  */
278 struct rockchip_pll_clock {
279         unsigned int            id;
280         const char              *name;
281         const char              *const *parent_names;
282         u8                      num_parents;
283         unsigned long           flags;
284         int                     con_offset;
285         int                     mode_offset;
286         int                     mode_shift;
287         int                     lock_shift;
288         enum rockchip_pll_type  type;
289         u8                      pll_flags;
290         struct rockchip_pll_rate_table *rate_table;
291 };
292
293 #define ROCKCHIP_PLL_SYNC_RATE          BIT(0)
294
295 #define PLL(_type, _id, _name, _pnames, _flags, _con, _mode, _mshift,   \
296                 _lshift, _pflags, _rtable)                              \
297         {                                                               \
298                 .id             = _id,                                  \
299                 .type           = _type,                                \
300                 .name           = _name,                                \
301                 .parent_names   = _pnames,                              \
302                 .num_parents    = ARRAY_SIZE(_pnames),                  \
303                 .flags          = CLK_GET_RATE_NOCACHE | _flags,        \
304                 .con_offset     = _con,                                 \
305                 .mode_offset    = _mode,                                \
306                 .mode_shift     = _mshift,                              \
307                 .lock_shift     = _lshift,                              \
308                 .pll_flags      = _pflags,                              \
309                 .rate_table     = _rtable,                              \
310         }
311
312 struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
313                 enum rockchip_pll_type pll_type,
314                 const char *name, const char *const *parent_names,
315                 u8 num_parents, int con_offset, int grf_lock_offset,
316                 int lock_shift, int mode_offset, int mode_shift,
317                 struct rockchip_pll_rate_table *rate_table,
318                 unsigned long flags, u8 clk_pll_flags);
319
320 struct rockchip_cpuclk_clksel {
321         int reg;
322         u32 val;
323 };
324
325 #define ROCKCHIP_CPUCLK_NUM_DIVIDERS    2
326 struct rockchip_cpuclk_rate_table {
327         unsigned long prate;
328         struct rockchip_cpuclk_clksel divs[ROCKCHIP_CPUCLK_NUM_DIVIDERS];
329 };
330
331 /**
332  * struct rockchip_cpuclk_reg_data - register offsets and masks of the cpuclock
333  * @core_reg:           register offset of the core settings register
334  * @div_core_shift:     core divider offset used to divide the pll value
335  * @div_core_mask:      core divider mask
336  * @mux_core_alt:       mux value to select alternate parent
337  * @mux_core_main:      mux value to select main parent of core
338  * @mux_core_shift:     offset of the core multiplexer
339  * @mux_core_mask:      core multiplexer mask
340  */
341 struct rockchip_cpuclk_reg_data {
342         int             core_reg;
343         u8              div_core_shift;
344         u32             div_core_mask;
345         u8              mux_core_alt;
346         u8              mux_core_main;
347         u8              mux_core_shift;
348         u32             mux_core_mask;
349 };
350
351 struct clk *rockchip_clk_register_cpuclk(const char *name,
352                         const char *const *parent_names, u8 num_parents,
353                         const struct rockchip_cpuclk_reg_data *reg_data,
354                         const struct rockchip_cpuclk_rate_table *rates,
355                         int nrates, void __iomem *reg_base, spinlock_t *lock);
356
357 struct clk *rockchip_clk_register_mmc(const char *name,
358                                 const char *const *parent_names, u8 num_parents,
359                                 void __iomem *reg, int shift);
360
361 /*
362  * DDRCLK flags, including method of setting the rate
363  * ROCKCHIP_DDRCLK_SIP: use SIP call to bl31 to change ddrclk rate.
364  */
365 #define ROCKCHIP_DDRCLK_SIP             BIT(0)
366
367 struct clk *rockchip_clk_register_ddrclk(const char *name, int flags,
368                                          const char *const *parent_names,
369                                          u8 num_parents, int mux_offset,
370                                          int mux_shift, int mux_width,
371                                          int div_shift, int div_width,
372                                          int ddr_flags, void __iomem *reg_base,
373                                          spinlock_t *lock);
374
375 #define ROCKCHIP_INVERTER_HIWORD_MASK   BIT(0)
376
377 struct clk *rockchip_clk_register_inverter(const char *name,
378                                 const char *const *parent_names, u8 num_parents,
379                                 void __iomem *reg, int shift, int flags,
380                                 spinlock_t *lock);
381
382 struct clk *rockchip_clk_register_muxgrf(const char *name,
383                                 const char *const *parent_names, u8 num_parents,
384                                 int flags, struct regmap *grf, int reg,
385                                 int shift, int width, int mux_flags);
386
387 #define PNAME(x) static const char *const x[] __initconst
388
389 enum rockchip_clk_branch_type {
390         branch_composite,
391         branch_mux,
392         branch_muxgrf,
393         branch_divider,
394         branch_fraction_divider,
395         branch_gate,
396         branch_mmc,
397         branch_inverter,
398         branch_factor,
399         branch_ddrclk,
400         branch_half_divider,
401 };
402
403 struct rockchip_clk_branch {
404         unsigned int                    id;
405         enum rockchip_clk_branch_type   branch_type;
406         const char                      *name;
407         const char                      *const *parent_names;
408         u8                              num_parents;
409         unsigned long                   flags;
410         int                             muxdiv_offset;
411         u8                              mux_shift;
412         u8                              mux_width;
413         u8                              mux_flags;
414         int                             div_offset;
415         u8                              div_shift;
416         u8                              div_width;
417         u8                              div_flags;
418         struct clk_div_table            *div_table;
419         int                             gate_offset;
420         u8                              gate_shift;
421         u8                              gate_flags;
422         struct rockchip_clk_branch      *child;
423 };
424
425 #define COMPOSITE(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw,\
426                   df, go, gs, gf)                               \
427         {                                                       \
428                 .id             = _id,                          \
429                 .branch_type    = branch_composite,             \
430                 .name           = cname,                        \
431                 .parent_names   = pnames,                       \
432                 .num_parents    = ARRAY_SIZE(pnames),           \
433                 .flags          = f,                            \
434                 .muxdiv_offset  = mo,                           \
435                 .mux_shift      = ms,                           \
436                 .mux_width      = mw,                           \
437                 .mux_flags      = mf,                           \
438                 .div_shift      = ds,                           \
439                 .div_width      = dw,                           \
440                 .div_flags      = df,                           \
441                 .gate_offset    = go,                           \
442                 .gate_shift     = gs,                           \
443                 .gate_flags     = gf,                           \
444         }
445
446 #define COMPOSITE_DIV_OFFSET(_id, cname, pnames, f, mo, ms, mw, \
447                              mf, do, ds, dw, df, go, gs, gf)    \
448         {                                                       \
449                 .id             = _id,                          \
450                 .branch_type    = branch_composite,             \
451                 .name           = cname,                        \
452                 .parent_names   = pnames,                       \
453                 .num_parents    = ARRAY_SIZE(pnames),           \
454                 .flags          = f,                            \
455                 .muxdiv_offset  = mo,                           \
456                 .mux_shift      = ms,                           \
457                 .mux_width      = mw,                           \
458                 .mux_flags      = mf,                           \
459                 .div_offset     = do,                           \
460                 .div_shift      = ds,                           \
461                 .div_width      = dw,                           \
462                 .div_flags      = df,                           \
463                 .gate_offset    = go,                           \
464                 .gate_shift     = gs,                           \
465                 .gate_flags     = gf,                           \
466         }
467
468 #define COMPOSITE_NOMUX(_id, cname, pname, f, mo, ds, dw, df,   \
469                         go, gs, gf)                             \
470         {                                                       \
471                 .id             = _id,                          \
472                 .branch_type    = branch_composite,             \
473                 .name           = cname,                        \
474                 .parent_names   = (const char *[]){ pname },    \
475                 .num_parents    = 1,                            \
476                 .flags          = f,                            \
477                 .muxdiv_offset  = mo,                           \
478                 .div_shift      = ds,                           \
479                 .div_width      = dw,                           \
480                 .div_flags      = df,                           \
481                 .gate_offset    = go,                           \
482                 .gate_shift     = gs,                           \
483                 .gate_flags     = gf,                           \
484         }
485
486 #define COMPOSITE_NOMUX_DIVTBL(_id, cname, pname, f, mo, ds, dw,\
487                                df, dt, go, gs, gf)              \
488         {                                                       \
489                 .id             = _id,                          \
490                 .branch_type    = branch_composite,             \
491                 .name           = cname,                        \
492                 .parent_names   = (const char *[]){ pname },    \
493                 .num_parents    = 1,                            \
494                 .flags          = f,                            \
495                 .muxdiv_offset  = mo,                           \
496                 .div_shift      = ds,                           \
497                 .div_width      = dw,                           \
498                 .div_flags      = df,                           \
499                 .div_table      = dt,                           \
500                 .gate_offset    = go,                           \
501                 .gate_shift     = gs,                           \
502                 .gate_flags     = gf,                           \
503         }
504
505 #define COMPOSITE_NODIV(_id, cname, pnames, f, mo, ms, mw, mf,  \
506                         go, gs, gf)                             \
507         {                                                       \
508                 .id             = _id,                          \
509                 .branch_type    = branch_composite,             \
510                 .name           = cname,                        \
511                 .parent_names   = pnames,                       \
512                 .num_parents    = ARRAY_SIZE(pnames),           \
513                 .flags          = f,                            \
514                 .muxdiv_offset  = mo,                           \
515                 .mux_shift      = ms,                           \
516                 .mux_width      = mw,                           \
517                 .mux_flags      = mf,                           \
518                 .gate_offset    = go,                           \
519                 .gate_shift     = gs,                           \
520                 .gate_flags     = gf,                           \
521         }
522
523 #define COMPOSITE_NOGATE(_id, cname, pnames, f, mo, ms, mw, mf, \
524                          ds, dw, df)                            \
525         {                                                       \
526                 .id             = _id,                          \
527                 .branch_type    = branch_composite,             \
528                 .name           = cname,                        \
529                 .parent_names   = pnames,                       \
530                 .num_parents    = ARRAY_SIZE(pnames),           \
531                 .flags          = f,                            \
532                 .muxdiv_offset  = mo,                           \
533                 .mux_shift      = ms,                           \
534                 .mux_width      = mw,                           \
535                 .mux_flags      = mf,                           \
536                 .div_shift      = ds,                           \
537                 .div_width      = dw,                           \
538                 .div_flags      = df,                           \
539                 .gate_offset    = -1,                           \
540         }
541
542 #define COMPOSITE_NOGATE_DIVTBL(_id, cname, pnames, f, mo, ms,  \
543                                 mw, mf, ds, dw, df, dt)         \
544         {                                                       \
545                 .id             = _id,                          \
546                 .branch_type    = branch_composite,             \
547                 .name           = cname,                        \
548                 .parent_names   = pnames,                       \
549                 .num_parents    = ARRAY_SIZE(pnames),           \
550                 .flags          = f,                            \
551                 .muxdiv_offset  = mo,                           \
552                 .mux_shift      = ms,                           \
553                 .mux_width      = mw,                           \
554                 .mux_flags      = mf,                           \
555                 .div_shift      = ds,                           \
556                 .div_width      = dw,                           \
557                 .div_flags      = df,                           \
558                 .div_table      = dt,                           \
559                 .gate_offset    = -1,                           \
560         }
561
562 #define COMPOSITE_FRAC(_id, cname, pname, f, mo, df, go, gs, gf)\
563         {                                                       \
564                 .id             = _id,                          \
565                 .branch_type    = branch_fraction_divider,      \
566                 .name           = cname,                        \
567                 .parent_names   = (const char *[]){ pname },    \
568                 .num_parents    = 1,                            \
569                 .flags          = f,                            \
570                 .muxdiv_offset  = mo,                           \
571                 .div_shift      = 16,                           \
572                 .div_width      = 16,                           \
573                 .div_flags      = df,                           \
574                 .gate_offset    = go,                           \
575                 .gate_shift     = gs,                           \
576                 .gate_flags     = gf,                           \
577         }
578
579 #define COMPOSITE_FRACMUX(_id, cname, pname, f, mo, df, go, gs, gf, ch) \
580         {                                                       \
581                 .id             = _id,                          \
582                 .branch_type    = branch_fraction_divider,      \
583                 .name           = cname,                        \
584                 .parent_names   = (const char *[]){ pname },    \
585                 .num_parents    = 1,                            \
586                 .flags          = f,                            \
587                 .muxdiv_offset  = mo,                           \
588                 .div_shift      = 16,                           \
589                 .div_width      = 16,                           \
590                 .div_flags      = df,                           \
591                 .gate_offset    = go,                           \
592                 .gate_shift     = gs,                           \
593                 .gate_flags     = gf,                           \
594                 .child          = ch,                           \
595         }
596
597 #define COMPOSITE_FRACMUX_NOGATE(_id, cname, pname, f, mo, df, ch) \
598         {                                                       \
599                 .id             = _id,                          \
600                 .branch_type    = branch_fraction_divider,      \
601                 .name           = cname,                        \
602                 .parent_names   = (const char *[]){ pname },    \
603                 .num_parents    = 1,                            \
604                 .flags          = f,                            \
605                 .muxdiv_offset  = mo,                           \
606                 .div_shift      = 16,                           \
607                 .div_width      = 16,                           \
608                 .div_flags      = df,                           \
609                 .gate_offset    = -1,                           \
610                 .child          = ch,                           \
611         }
612
613 #define COMPOSITE_DDRCLK(_id, cname, pnames, f, mo, ms, mw,     \
614                          ds, dw, df)                            \
615         {                                                       \
616                 .id             = _id,                          \
617                 .branch_type    = branch_ddrclk,                \
618                 .name           = cname,                        \
619                 .parent_names   = pnames,                       \
620                 .num_parents    = ARRAY_SIZE(pnames),           \
621                 .flags          = f,                            \
622                 .muxdiv_offset  = mo,                           \
623                 .mux_shift      = ms,                           \
624                 .mux_width      = mw,                           \
625                 .div_shift      = ds,                           \
626                 .div_width      = dw,                           \
627                 .div_flags      = df,                           \
628                 .gate_offset    = -1,                           \
629         }
630
631 #define MUX(_id, cname, pnames, f, o, s, w, mf)                 \
632         {                                                       \
633                 .id             = _id,                          \
634                 .branch_type    = branch_mux,                   \
635                 .name           = cname,                        \
636                 .parent_names   = pnames,                       \
637                 .num_parents    = ARRAY_SIZE(pnames),           \
638                 .flags          = f,                            \
639                 .muxdiv_offset  = o,                            \
640                 .mux_shift      = s,                            \
641                 .mux_width      = w,                            \
642                 .mux_flags      = mf,                           \
643                 .gate_offset    = -1,                           \
644         }
645
646 #define MUXGRF(_id, cname, pnames, f, o, s, w, mf)              \
647         {                                                       \
648                 .id             = _id,                          \
649                 .branch_type    = branch_muxgrf,                \
650                 .name           = cname,                        \
651                 .parent_names   = pnames,                       \
652                 .num_parents    = ARRAY_SIZE(pnames),           \
653                 .flags          = f,                            \
654                 .muxdiv_offset  = o,                            \
655                 .mux_shift      = s,                            \
656                 .mux_width      = w,                            \
657                 .mux_flags      = mf,                           \
658                 .gate_offset    = -1,                           \
659         }
660
661 #define DIV(_id, cname, pname, f, o, s, w, df)                  \
662         {                                                       \
663                 .id             = _id,                          \
664                 .branch_type    = branch_divider,               \
665                 .name           = cname,                        \
666                 .parent_names   = (const char *[]){ pname },    \
667                 .num_parents    = 1,                            \
668                 .flags          = f,                            \
669                 .muxdiv_offset  = o,                            \
670                 .div_shift      = s,                            \
671                 .div_width      = w,                            \
672                 .div_flags      = df,                           \
673                 .gate_offset    = -1,                           \
674         }
675
676 #define DIVTBL(_id, cname, pname, f, o, s, w, df, dt)           \
677         {                                                       \
678                 .id             = _id,                          \
679                 .branch_type    = branch_divider,               \
680                 .name           = cname,                        \
681                 .parent_names   = (const char *[]){ pname },    \
682                 .num_parents    = 1,                            \
683                 .flags          = f,                            \
684                 .muxdiv_offset  = o,                            \
685                 .div_shift      = s,                            \
686                 .div_width      = w,                            \
687                 .div_flags      = df,                           \
688                 .div_table      = dt,                           \
689         }
690
691 #define GATE(_id, cname, pname, f, o, b, gf)                    \
692         {                                                       \
693                 .id             = _id,                          \
694                 .branch_type    = branch_gate,                  \
695                 .name           = cname,                        \
696                 .parent_names   = (const char *[]){ pname },    \
697                 .num_parents    = 1,                            \
698                 .flags          = f,                            \
699                 .gate_offset    = o,                            \
700                 .gate_shift     = b,                            \
701                 .gate_flags     = gf,                           \
702         }
703
704 #define MMC(_id, cname, pname, offset, shift)                   \
705         {                                                       \
706                 .id             = _id,                          \
707                 .branch_type    = branch_mmc,                   \
708                 .name           = cname,                        \
709                 .parent_names   = (const char *[]){ pname },    \
710                 .num_parents    = 1,                            \
711                 .muxdiv_offset  = offset,                       \
712                 .div_shift      = shift,                        \
713         }
714
715 #define INVERTER(_id, cname, pname, io, is, if)                 \
716         {                                                       \
717                 .id             = _id,                          \
718                 .branch_type    = branch_inverter,              \
719                 .name           = cname,                        \
720                 .parent_names   = (const char *[]){ pname },    \
721                 .num_parents    = 1,                            \
722                 .muxdiv_offset  = io,                           \
723                 .div_shift      = is,                           \
724                 .div_flags      = if,                           \
725         }
726
727 #define FACTOR(_id, cname, pname,  f, fm, fd)                   \
728         {                                                       \
729                 .id             = _id,                          \
730                 .branch_type    = branch_factor,                \
731                 .name           = cname,                        \
732                 .parent_names   = (const char *[]){ pname },    \
733                 .num_parents    = 1,                            \
734                 .flags          = f,                            \
735                 .div_shift      = fm,                           \
736                 .div_width      = fd,                           \
737         }
738
739 #define FACTOR_GATE(_id, cname, pname,  f, fm, fd, go, gb, gf)  \
740         {                                                       \
741                 .id             = _id,                          \
742                 .branch_type    = branch_factor,                \
743                 .name           = cname,                        \
744                 .parent_names   = (const char *[]){ pname },    \
745                 .num_parents    = 1,                            \
746                 .flags          = f,                            \
747                 .div_shift      = fm,                           \
748                 .div_width      = fd,                           \
749                 .gate_offset    = go,                           \
750                 .gate_shift     = gb,                           \
751                 .gate_flags     = gf,                           \
752         }
753
754 #define COMPOSITE_HALFDIV(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw,\
755                           df, go, gs, gf)                               \
756         {                                                       \
757                 .id             = _id,                          \
758                 .branch_type    = branch_half_divider,          \
759                 .name           = cname,                        \
760                 .parent_names   = pnames,                       \
761                 .num_parents    = ARRAY_SIZE(pnames),           \
762                 .flags          = f,                            \
763                 .muxdiv_offset  = mo,                           \
764                 .mux_shift      = ms,                           \
765                 .mux_width      = mw,                           \
766                 .mux_flags      = mf,                           \
767                 .div_shift      = ds,                           \
768                 .div_width      = dw,                           \
769                 .div_flags      = df,                           \
770                 .gate_offset    = go,                           \
771                 .gate_shift     = gs,                           \
772                 .gate_flags     = gf,                           \
773         }
774
775 #define COMPOSITE_NOGATE_HALFDIV(_id, cname, pnames, f, mo, ms, mw, mf, \
776                                  ds, dw, df)                            \
777         {                                                       \
778                 .id             = _id,                          \
779                 .branch_type    = branch_half_divider,          \
780                 .name           = cname,                        \
781                 .parent_names   = pnames,                       \
782                 .num_parents    = ARRAY_SIZE(pnames),           \
783                 .flags          = f,                            \
784                 .muxdiv_offset  = mo,                           \
785                 .mux_shift      = ms,                           \
786                 .mux_width      = mw,                           \
787                 .mux_flags      = mf,                           \
788                 .div_shift      = ds,                           \
789                 .div_width      = dw,                           \
790                 .div_flags      = df,                           \
791                 .gate_offset    = -1,                           \
792         }
793
794 #define COMPOSITE_NOMUX_HALFDIV(_id, cname, pname, f, mo, ds, dw, df,   \
795                         go, gs, gf)                             \
796         {                                                       \
797                 .id             = _id,                          \
798                 .branch_type    = branch_half_divider,          \
799                 .name           = cname,                        \
800                 .parent_names   = (const char *[]){ pname },    \
801                 .num_parents    = 1,                            \
802                 .flags          = f,                            \
803                 .muxdiv_offset  = mo,                           \
804                 .div_shift      = ds,                           \
805                 .div_width      = dw,                           \
806                 .div_flags      = df,                           \
807                 .gate_offset    = go,                           \
808                 .gate_shift     = gs,                           \
809                 .gate_flags     = gf,                           \
810         }
811
812 #define DIV_HALF(_id, cname, pname, f, o, s, w, df)                     \
813         {                                                       \
814                 .id             = _id,                          \
815                 .branch_type    = branch_half_divider,          \
816                 .name           = cname,                        \
817                 .parent_names   = (const char *[]){ pname },    \
818                 .num_parents    = 1,                            \
819                 .flags          = f,                            \
820                 .muxdiv_offset  = o,                            \
821                 .div_shift      = s,                            \
822                 .div_width      = w,                            \
823                 .div_flags      = df,                           \
824                 .gate_offset    = -1,                           \
825         }
826
827 /* SGRF clocks are only accessible from secure mode, so not controllable */
828 #define SGRF_GATE(_id, cname, pname)                            \
829                 FACTOR(_id, cname, pname, 0, 1, 1)
830
831 struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np,
832                         void __iomem *base, unsigned long nr_clks);
833 void rockchip_clk_of_add_provider(struct device_node *np,
834                                 struct rockchip_clk_provider *ctx);
835 void rockchip_clk_add_lookup(struct rockchip_clk_provider *ctx,
836                              struct clk *clk, unsigned int id);
837 void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
838                                     struct rockchip_clk_branch *list,
839                                     unsigned int nr_clk);
840 void rockchip_clk_register_plls(struct rockchip_clk_provider *ctx,
841                                 struct rockchip_pll_clock *pll_list,
842                                 unsigned int nr_pll, int grf_lock_offset);
843 void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx,
844                         unsigned int lookup_id, const char *name,
845                         const char *const *parent_names, u8 num_parents,
846                         const struct rockchip_cpuclk_reg_data *reg_data,
847                         const struct rockchip_cpuclk_rate_table *rates,
848                         int nrates);
849 void rockchip_clk_protect_critical(const char *const clocks[], int nclocks);
850 void rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx,
851                                         unsigned int reg, void (*cb)(void));
852
853 #define ROCKCHIP_SOFTRST_HIWORD_MASK    BIT(0)
854
855 struct clk *rockchip_clk_register_halfdiv(const char *name,
856                                           const char *const *parent_names,
857                                           u8 num_parents, void __iomem *base,
858                                           int muxdiv_offset, u8 mux_shift,
859                                           u8 mux_width, u8 mux_flags,
860                                           u8 div_shift, u8 div_width,
861                                           u8 div_flags, int gate_offset,
862                                           u8 gate_shift, u8 gate_flags,
863                                           unsigned long flags,
864                                           spinlock_t *lock);
865
866 #ifdef CONFIG_RESET_CONTROLLER
867 void rockchip_register_softrst(struct device_node *np,
868                                unsigned int num_regs,
869                                void __iomem *base, u8 flags);
870 #else
871 static inline void rockchip_register_softrst(struct device_node *np,
872                                unsigned int num_regs,
873                                void __iomem *base, u8 flags)
874 {
875 }
876 #endif
877
878 #endif