c1e49b2767ec46d1343e184e4c49699442ae4b6b
[firefly-linux-kernel-4.4.55.git] / drivers / clk / rockchip / clk.h
1 /*
2  * Copyright (c) 2014 MundoReader S.L.
3  * Author: Heiko Stuebner <heiko@sntech.de>
4  *
5  * Copyright (c) 2015 Rockchip Electronics Co. Ltd.
6  * Author: Xing Zheng <zhengxing@rock-chips.com>
7  *
8  * based on
9  *
10  * samsung/clk.h
11  * Copyright (c) 2013 Samsung Electronics Co., Ltd.
12  * Copyright (c) 2013 Linaro Ltd.
13  * Author: Thomas Abraham <thomas.ab@samsung.com>
14  *
15  * This program is free software; you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License as published by
17  * the Free Software Foundation; either version 2 of the License, or
18  * (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  */
25
26 #ifndef CLK_ROCKCHIP_CLK_H
27 #define CLK_ROCKCHIP_CLK_H
28
29 #include <linux/io.h>
30 #include <linux/clk-provider.h>
31
32 struct clk;
33
34 #define HIWORD_UPDATE(val, mask, shift) \
35                 ((val) << (shift) | (mask) << ((shift) + 16))
36
37 /* register positions shared by RK2928, RK3036, RK3066, RK3188 and RK3228 */
38 #define RK2928_PLL_CON(x)               ((x) * 0x4)
39 #define RK2928_MODE_CON         0x40
40 #define RK2928_CLKSEL_CON(x)    ((x) * 0x4 + 0x44)
41 #define RK2928_CLKGATE_CON(x)   ((x) * 0x4 + 0xd0)
42 #define RK2928_GLB_SRST_FST             0x100
43 #define RK2928_GLB_SRST_SND             0x104
44 #define RK2928_SOFTRST_CON(x)   ((x) * 0x4 + 0x110)
45 #define RK2928_MISC_CON         0x134
46
47 #define RK3036_SDMMC_CON0               0x144
48 #define RK3036_SDMMC_CON1               0x148
49 #define RK3036_SDIO_CON0                0x14c
50 #define RK3036_SDIO_CON1                0x150
51 #define RK3036_EMMC_CON0                0x154
52 #define RK3036_EMMC_CON1                0x158
53
54 #define RK3228_GLB_SRST_FST             0x1f0
55 #define RK3228_GLB_SRST_SND             0x1f4
56 #define RK3228_SDMMC_CON0               0x1c0
57 #define RK3228_SDMMC_CON1               0x1c4
58 #define RK3228_SDIO_CON0                0x1c8
59 #define RK3228_SDIO_CON1                0x1cc
60 #define RK3228_EMMC_CON0                0x1d8
61 #define RK3228_EMMC_CON1                0x1dc
62
63 #define RK3288_PLL_CON(x)               RK2928_PLL_CON(x)
64 #define RK3288_MODE_CON                 0x50
65 #define RK3288_CLKSEL_CON(x)            ((x) * 0x4 + 0x60)
66 #define RK3288_CLKGATE_CON(x)           ((x) * 0x4 + 0x160)
67 #define RK3288_GLB_SRST_FST             0x1b0
68 #define RK3288_GLB_SRST_SND             0x1b4
69 #define RK3288_SOFTRST_CON(x)           ((x) * 0x4 + 0x1b8)
70 #define RK3288_MISC_CON                 0x1e8
71 #define RK3288_SDMMC_CON0               0x200
72 #define RK3288_SDMMC_CON1               0x204
73 #define RK3288_SDIO0_CON0               0x208
74 #define RK3288_SDIO0_CON1               0x20c
75 #define RK3288_SDIO1_CON0               0x210
76 #define RK3288_SDIO1_CON1               0x214
77 #define RK3288_EMMC_CON0                0x218
78 #define RK3288_EMMC_CON1                0x21c
79
80 #define RK3328_PLL_CON(x)               RK2928_PLL_CON(x)
81 #define RK3328_CLKSEL_CON(x)            ((x) * 0x4 + 0x100)
82 #define RK3328_CLKGATE_CON(x)           ((x) * 0x4 + 0x200)
83 #define RK3328_GRFCLKSEL_CON(x)         ((x) * 0x4 + 0x100)
84 #define RK3328_GLB_SRST_FST             0x9c
85 #define RK3328_GLB_SRST_SND             0x98
86 #define RK3328_SOFTRST_CON(x)           ((x) * 0x4 + 0x300)
87 #define RK3328_MODE_CON                 0x80
88 #define RK3328_MISC_CON                 0x84
89 #define RK3328_SDMMC_CON0               0x380
90 #define RK3328_SDMMC_CON1               0x384
91 #define RK3328_SDIO_CON0                0x388
92 #define RK3328_SDIO_CON1                0x38c
93 #define RK3328_EMMC_CON0                0x390
94 #define RK3328_EMMC_CON1                0x394
95 #define RK3328_SDMMC_EXT_CON0           0x398
96 #define RK3328_SDMMC_EXT_CON1           0x39C
97
98 #define RK3368_PLL_CON(x)               RK2928_PLL_CON(x)
99 #define RK3368_CLKSEL_CON(x)            ((x) * 0x4 + 0x100)
100 #define RK3368_CLKGATE_CON(x)           ((x) * 0x4 + 0x200)
101 #define RK3368_GLB_SRST_FST             0x280
102 #define RK3368_GLB_SRST_SND             0x284
103 #define RK3368_SOFTRST_CON(x)           ((x) * 0x4 + 0x300)
104 #define RK3368_MISC_CON                 0x380
105 #define RK3368_SDMMC_CON0               0x400
106 #define RK3368_SDMMC_CON1               0x404
107 #define RK3368_SDIO0_CON0               0x408
108 #define RK3368_SDIO0_CON1               0x40c
109 #define RK3368_SDIO1_CON0               0x410
110 #define RK3368_SDIO1_CON1               0x414
111 #define RK3368_EMMC_CON0                0x418
112 #define RK3368_EMMC_CON1                0x41c
113
114 #define RK3399_PLL_CON(x)               RK2928_PLL_CON(x)
115 #define RK3399_CLKSEL_CON(x)            ((x) * 0x4 + 0x100)
116 #define RK3399_CLKGATE_CON(x)           ((x) * 0x4 + 0x300)
117 #define RK3399_SOFTRST_CON(x)           ((x) * 0x4 + 0x400)
118 #define RK3399_GLB_SRST_FST             0x500
119 #define RK3399_GLB_SRST_SND             0x504
120 #define RK3399_GLB_CNT_TH               0x508
121 #define RK3399_MISC_CON                 0x50c
122 #define RK3399_RST_CON                  0x510
123 #define RK3399_RST_ST                   0x514
124 #define RK3399_SDMMC_CON0               0x580
125 #define RK3399_SDMMC_CON1               0x584
126 #define RK3399_SDIO_CON0                0x588
127 #define RK3399_SDIO_CON1                0x58c
128
129 #define RK3399_PMU_PLL_CON(x)           RK2928_PLL_CON(x)
130 #define RK3399_PMU_CLKSEL_CON(x)        ((x) * 0x4 + 0x80)
131 #define RK3399_PMU_CLKGATE_CON(x)       ((x) * 0x4 + 0x100)
132 #define RK3399_PMU_SOFTRST_CON(x)       ((x) * 0x4 + 0x110)
133 #define RK3399_PMU_RSTNHOLD_CON(x)      ((x) * 0x4 + 0x120)
134 #define RK3399_PMU_GATEDIS_CON(x)       ((x) * 0x4 + 0x130)
135
136 enum rockchip_pll_type {
137         pll_rk3036,
138         pll_rk3066,
139         pll_rk3328,
140         pll_rk3366,
141         pll_rk3399,
142 };
143
144 #define RK3036_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1,      \
145                         _postdiv2, _dsmpd, _frac)               \
146 {                                                               \
147         .rate   = _rate##U,                                     \
148         .fbdiv = _fbdiv,                                        \
149         .postdiv1 = _postdiv1,                                  \
150         .refdiv = _refdiv,                                      \
151         .postdiv2 = _postdiv2,                                  \
152         .dsmpd = _dsmpd,                                        \
153         .frac = _frac,                                          \
154 }
155
156 #define RK3066_PLL_RATE(_rate, _nr, _nf, _no)   \
157 {                                               \
158         .rate   = _rate##U,                     \
159         .nr = _nr,                              \
160         .nf = _nf,                              \
161         .no = _no,                              \
162         .nb = ((_nf) < 2) ? 1 : (_nf) >> 1,     \
163 }
164
165 #define RK3066_PLL_RATE_NB(_rate, _nr, _nf, _no, _nb)           \
166 {                                                               \
167         .rate   = _rate##U,                                     \
168         .nr = _nr,                                              \
169         .nf = _nf,                                              \
170         .no = _no,                                              \
171         .nb = _nb,                                              \
172 }
173
174 /**
175  * struct rockchip_clk_provider - information about clock provider
176  * @reg_base: virtual address for the register base.
177  * @clk_data: holds clock related data like clk* and number of clocks.
178  * @cru_node: device-node of the clock-provider
179  * @grf: regmap of the general-register-files syscon
180  * @lock: maintains exclusion between callbacks for a given clock-provider.
181  */
182 struct rockchip_clk_provider {
183         void __iomem *reg_base;
184         struct clk_onecell_data clk_data;
185         struct device_node *cru_node;
186         struct regmap *grf;
187         spinlock_t lock;
188 };
189
190 struct rockchip_pll_rate_table {
191         unsigned long rate;
192         unsigned int nr;
193         unsigned int nf;
194         unsigned int no;
195         unsigned int nb;
196         /* for RK3036/RK3399 */
197         unsigned int fbdiv;
198         unsigned int postdiv1;
199         unsigned int refdiv;
200         unsigned int postdiv2;
201         unsigned int dsmpd;
202         unsigned int frac;
203 };
204
205 /**
206  * struct rockchip_pll_clock - information about pll clock
207  * @id: platform specific id of the clock.
208  * @name: name of this pll clock.
209  * @parent_names: name of the parent clock.
210  * @num_parents: number of parents
211  * @flags: optional flags for basic clock.
212  * @con_offset: offset of the register for configuring the PLL.
213  * @mode_offset: offset of the register for configuring the PLL-mode.
214  * @mode_shift: offset inside the mode-register for the mode of this pll.
215  * @lock_shift: offset inside the lock register for the lock status.
216  * @type: Type of PLL to be registered.
217  * @pll_flags: hardware-specific flags
218  * @rate_table: Table of usable pll rates
219  *
220  * Flags:
221  * ROCKCHIP_PLL_SYNC_RATE - check rate parameters to match against the
222  *      rate_table parameters and ajust them if necessary.
223  */
224 struct rockchip_pll_clock {
225         unsigned int            id;
226         const char              *name;
227         const char              *const *parent_names;
228         u8                      num_parents;
229         unsigned long           flags;
230         int                     con_offset;
231         int                     mode_offset;
232         int                     mode_shift;
233         int                     lock_shift;
234         enum rockchip_pll_type  type;
235         u8                      pll_flags;
236         struct rockchip_pll_rate_table *rate_table;
237 };
238
239 #define ROCKCHIP_PLL_SYNC_RATE          BIT(0)
240
241 #define PLL(_type, _id, _name, _pnames, _flags, _con, _mode, _mshift,   \
242                 _lshift, _pflags, _rtable)                              \
243         {                                                               \
244                 .id             = _id,                                  \
245                 .type           = _type,                                \
246                 .name           = _name,                                \
247                 .parent_names   = _pnames,                              \
248                 .num_parents    = ARRAY_SIZE(_pnames),                  \
249                 .flags          = CLK_GET_RATE_NOCACHE | _flags,        \
250                 .con_offset     = _con,                                 \
251                 .mode_offset    = _mode,                                \
252                 .mode_shift     = _mshift,                              \
253                 .lock_shift     = _lshift,                              \
254                 .pll_flags      = _pflags,                              \
255                 .rate_table     = _rtable,                              \
256         }
257
258 struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
259                 enum rockchip_pll_type pll_type,
260                 const char *name, const char *const *parent_names,
261                 u8 num_parents, int con_offset, int grf_lock_offset,
262                 int lock_shift, int mode_offset, int mode_shift,
263                 struct rockchip_pll_rate_table *rate_table,
264                 unsigned long flags, u8 clk_pll_flags);
265
266 struct rockchip_cpuclk_clksel {
267         int reg;
268         u32 val;
269 };
270
271 #define ROCKCHIP_CPUCLK_NUM_DIVIDERS    2
272 struct rockchip_cpuclk_rate_table {
273         unsigned long prate;
274         struct rockchip_cpuclk_clksel divs[ROCKCHIP_CPUCLK_NUM_DIVIDERS];
275 };
276
277 /**
278  * struct rockchip_cpuclk_reg_data - describes register offsets and masks of the cpuclock
279  * @core_reg:           register offset of the core settings register
280  * @div_core_shift:     core divider offset used to divide the pll value
281  * @div_core_mask:      core divider mask
282  * @mux_core_alt:       mux value to select alternate parent
283  * @mux_core_main:      mux value to select main parent of core
284  * @mux_core_shift:     offset of the core multiplexer
285  * @mux_core_mask:      core multiplexer mask
286  */
287 struct rockchip_cpuclk_reg_data {
288         int             core_reg;
289         u8              div_core_shift;
290         u32             div_core_mask;
291         u8              mux_core_alt;
292         u8              mux_core_main;
293         u8              mux_core_shift;
294         u32             mux_core_mask;
295 };
296
297 struct clk *rockchip_clk_register_cpuclk(const char *name,
298                         const char *const *parent_names, u8 num_parents,
299                         const struct rockchip_cpuclk_reg_data *reg_data,
300                         const struct rockchip_cpuclk_rate_table *rates,
301                         int nrates, void __iomem *reg_base, spinlock_t *lock);
302
303 struct clk *rockchip_clk_register_mmc(const char *name,
304                                 const char *const *parent_names, u8 num_parents,
305                                 void __iomem *reg, int shift);
306
307 /*
308  * for COMPOSITE_DDRCLK div_flag,
309  * there may have serval ways to set ddr clock, use
310  * this flag to distinguish them.
311  * ROCKCHIP_DDRCLK_SIP: use SIP call to bl31 to change ddrclk rate.
312  * ROCKCHIP_DDRCLK_SCPI: use SCPI APIs to let mcu change ddrclk rate.
313  */
314 #define ROCKCHIP_DDRCLK_SIP             0x01
315 #define ROCKCHIP_DDRCLK_SCPI            0x02
316
317 struct clk *rockchip_clk_register_ddrclk(const char *name, int flags,
318                                          const char *const *parent_names,
319                                          u8 num_parents, int mux_offset,
320                                          int mux_shift, int mux_width,
321                                          int div_shift, int div_width,
322                                          int ddr_flags, void __iomem *reg_base,
323                                          spinlock_t *lock);
324
325 #define ROCKCHIP_INVERTER_HIWORD_MASK   BIT(0)
326
327 struct clk *rockchip_clk_register_inverter(const char *name,
328                                 const char *const *parent_names, u8 num_parents,
329                                 void __iomem *reg, int shift, int flags,
330                                 spinlock_t *lock);
331
332 struct clk *rockchip_clk_register_muxgrf(const char *name,
333                                 const char *const *parent_names, u8 num_parents,
334                                 int flags, struct regmap *grf, int reg,
335                                 int shift, int width, int mux_flags);
336
337 #define PNAME(x) static const char *const x[] __initconst
338
339 enum rockchip_clk_branch_type {
340         branch_composite,
341         branch_mux,
342         branch_muxgrf,
343         branch_divider,
344         branch_fraction_divider,
345         branch_gate,
346         branch_mmc,
347         branch_inverter,
348         branch_factor,
349         branch_ddrc,
350 };
351
352 struct rockchip_clk_branch {
353         unsigned int                    id;
354         enum rockchip_clk_branch_type   branch_type;
355         const char                      *name;
356         const char                      *const *parent_names;
357         u8                              num_parents;
358         unsigned long                   flags;
359         int                             muxdiv_offset;
360         u8                              mux_shift;
361         u8                              mux_width;
362         u8                              mux_flags;
363         u8                              div_shift;
364         u8                              div_width;
365         u8                              div_flags;
366         struct clk_div_table            *div_table;
367         int                             gate_offset;
368         u8                              gate_shift;
369         u8                              gate_flags;
370         struct rockchip_clk_branch      *child;
371 };
372
373 #define COMPOSITE(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw,\
374                   df, go, gs, gf)                               \
375         {                                                       \
376                 .id             = _id,                          \
377                 .branch_type    = branch_composite,             \
378                 .name           = cname,                        \
379                 .parent_names   = pnames,                       \
380                 .num_parents    = ARRAY_SIZE(pnames),           \
381                 .flags          = f,                            \
382                 .muxdiv_offset  = mo,                           \
383                 .mux_shift      = ms,                           \
384                 .mux_width      = mw,                           \
385                 .mux_flags      = mf,                           \
386                 .div_shift      = ds,                           \
387                 .div_width      = dw,                           \
388                 .div_flags      = df,                           \
389                 .gate_offset    = go,                           \
390                 .gate_shift     = gs,                           \
391                 .gate_flags     = gf,                           \
392         }
393
394 #define COMPOSITE_NOMUX(_id, cname, pname, f, mo, ds, dw, df,   \
395                         go, gs, gf)                             \
396         {                                                       \
397                 .id             = _id,                          \
398                 .branch_type    = branch_composite,             \
399                 .name           = cname,                        \
400                 .parent_names   = (const char *[]){ pname },    \
401                 .num_parents    = 1,                            \
402                 .flags          = f,                            \
403                 .muxdiv_offset  = mo,                           \
404                 .div_shift      = ds,                           \
405                 .div_width      = dw,                           \
406                 .div_flags      = df,                           \
407                 .gate_offset    = go,                           \
408                 .gate_shift     = gs,                           \
409                 .gate_flags     = gf,                           \
410         }
411
412 #define COMPOSITE_NOMUX_DIVTBL(_id, cname, pname, f, mo, ds, dw,\
413                                df, dt, go, gs, gf)              \
414         {                                                       \
415                 .id             = _id,                          \
416                 .branch_type    = branch_composite,             \
417                 .name           = cname,                        \
418                 .parent_names   = (const char *[]){ pname },    \
419                 .num_parents    = 1,                            \
420                 .flags          = f,                            \
421                 .muxdiv_offset  = mo,                           \
422                 .div_shift      = ds,                           \
423                 .div_width      = dw,                           \
424                 .div_flags      = df,                           \
425                 .div_table      = dt,                           \
426                 .gate_offset    = go,                           \
427                 .gate_shift     = gs,                           \
428                 .gate_flags     = gf,                           \
429         }
430
431 #define COMPOSITE_NODIV(_id, cname, pnames, f, mo, ms, mw, mf,  \
432                         go, gs, gf)                             \
433         {                                                       \
434                 .id             = _id,                          \
435                 .branch_type    = branch_composite,             \
436                 .name           = cname,                        \
437                 .parent_names   = pnames,                       \
438                 .num_parents    = ARRAY_SIZE(pnames),           \
439                 .flags          = f,                            \
440                 .muxdiv_offset  = mo,                           \
441                 .mux_shift      = ms,                           \
442                 .mux_width      = mw,                           \
443                 .mux_flags      = mf,                           \
444                 .gate_offset    = go,                           \
445                 .gate_shift     = gs,                           \
446                 .gate_flags     = gf,                           \
447         }
448
449 #define COMPOSITE_NOGATE(_id, cname, pnames, f, mo, ms, mw, mf, \
450                          ds, dw, df)                            \
451         {                                                       \
452                 .id             = _id,                          \
453                 .branch_type    = branch_composite,             \
454                 .name           = cname,                        \
455                 .parent_names   = pnames,                       \
456                 .num_parents    = ARRAY_SIZE(pnames),           \
457                 .flags          = f,                            \
458                 .muxdiv_offset  = mo,                           \
459                 .mux_shift      = ms,                           \
460                 .mux_width      = mw,                           \
461                 .mux_flags      = mf,                           \
462                 .div_shift      = ds,                           \
463                 .div_width      = dw,                           \
464                 .div_flags      = df,                           \
465                 .gate_offset    = -1,                           \
466         }
467
468 #define COMPOSITE_NOGATE_DIVTBL(_id, cname, pnames, f, mo, ms,  \
469                                 mw, mf, ds, dw, df, dt)         \
470         {                                                       \
471                 .id             = _id,                          \
472                 .branch_type    = branch_composite,             \
473                 .name           = cname,                        \
474                 .parent_names   = pnames,                       \
475                 .num_parents    = ARRAY_SIZE(pnames),           \
476                 .flags          = f,                            \
477                 .muxdiv_offset  = mo,                           \
478                 .mux_shift      = ms,                           \
479                 .mux_width      = mw,                           \
480                 .mux_flags      = mf,                           \
481                 .div_shift      = ds,                           \
482                 .div_width      = dw,                           \
483                 .div_flags      = df,                           \
484                 .div_table      = dt,                           \
485                 .gate_offset    = -1,                           \
486         }
487
488 #define COMPOSITE_FRAC(_id, cname, pname, f, mo, df, go, gs, gf)\
489         {                                                       \
490                 .id             = _id,                          \
491                 .branch_type    = branch_fraction_divider,      \
492                 .name           = cname,                        \
493                 .parent_names   = (const char *[]){ pname },    \
494                 .num_parents    = 1,                            \
495                 .flags          = f,                            \
496                 .muxdiv_offset  = mo,                           \
497                 .div_shift      = 16,                           \
498                 .div_width      = 16,                           \
499                 .div_flags      = df,                           \
500                 .gate_offset    = go,                           \
501                 .gate_shift     = gs,                           \
502                 .gate_flags     = gf,                           \
503         }
504
505 #define COMPOSITE_FRACMUX(_id, cname, pname, f, mo, df, go, gs, gf, ch) \
506         {                                                       \
507                 .id             = _id,                          \
508                 .branch_type    = branch_fraction_divider,      \
509                 .name           = cname,                        \
510                 .parent_names   = (const char *[]){ pname },    \
511                 .num_parents    = 1,                            \
512                 .flags          = f,                            \
513                 .muxdiv_offset  = mo,                           \
514                 .div_shift      = 16,                           \
515                 .div_width      = 16,                           \
516                 .div_flags      = df,                           \
517                 .gate_offset    = go,                           \
518                 .gate_shift     = gs,                           \
519                 .gate_flags     = gf,                           \
520                 .child          = ch,                           \
521         }
522
523 #define COMPOSITE_FRACMUX_NOGATE(_id, cname, pname, f, mo, df, ch) \
524         {                                                       \
525                 .id             = _id,                          \
526                 .branch_type    = branch_fraction_divider,      \
527                 .name           = cname,                        \
528                 .parent_names   = (const char *[]){ pname },    \
529                 .num_parents    = 1,                            \
530                 .flags          = f,                            \
531                 .muxdiv_offset  = mo,                           \
532                 .div_shift      = 16,                           \
533                 .div_width      = 16,                           \
534                 .div_flags      = df,                           \
535                 .gate_offset    = -1,                           \
536                 .child          = ch,                           \
537         }
538
539 #define COMPOSITE_DDRCLK(_id, cname, pnames, f, mo, ms, mw,     \
540                          ds, dw, df)                            \
541         {                                                       \
542                 .id             = _id,                          \
543                 .branch_type    = branch_ddrc,                  \
544                 .name           = cname,                        \
545                 .parent_names   = pnames,                       \
546                 .num_parents    = ARRAY_SIZE(pnames),           \
547                 .flags          = f,                            \
548                 .muxdiv_offset  = mo,                           \
549                 .mux_shift      = ms,                           \
550                 .mux_width      = mw,                           \
551                 .div_shift      = ds,                           \
552                 .div_width      = dw,                           \
553                 .div_flags      = df,                           \
554                 .gate_offset    = -1,                           \
555         }
556
557 #define MUX(_id, cname, pnames, f, o, s, w, mf)                 \
558         {                                                       \
559                 .id             = _id,                          \
560                 .branch_type    = branch_mux,                   \
561                 .name           = cname,                        \
562                 .parent_names   = pnames,                       \
563                 .num_parents    = ARRAY_SIZE(pnames),           \
564                 .flags          = f,                            \
565                 .muxdiv_offset  = o,                            \
566                 .mux_shift      = s,                            \
567                 .mux_width      = w,                            \
568                 .mux_flags      = mf,                           \
569                 .gate_offset    = -1,                           \
570         }
571
572 #define MUXGRF(_id, cname, pnames, f, o, s, w, mf)              \
573         {                                                       \
574                 .id             = _id,                          \
575                 .branch_type    = branch_muxgrf,                \
576                 .name           = cname,                        \
577                 .parent_names   = pnames,                       \
578                 .num_parents    = ARRAY_SIZE(pnames),           \
579                 .flags          = f,                            \
580                 .muxdiv_offset  = o,                            \
581                 .mux_shift      = s,                            \
582                 .mux_width      = w,                            \
583                 .mux_flags      = mf,                           \
584                 .gate_offset    = -1,                           \
585         }
586
587 #define DIV(_id, cname, pname, f, o, s, w, df)                  \
588         {                                                       \
589                 .id             = _id,                          \
590                 .branch_type    = branch_divider,               \
591                 .name           = cname,                        \
592                 .parent_names   = (const char *[]){ pname },    \
593                 .num_parents    = 1,                            \
594                 .flags          = f,                            \
595                 .muxdiv_offset  = o,                            \
596                 .div_shift      = s,                            \
597                 .div_width      = w,                            \
598                 .div_flags      = df,                           \
599                 .gate_offset    = -1,                           \
600         }
601
602 #define DIVTBL(_id, cname, pname, f, o, s, w, df, dt)           \
603         {                                                       \
604                 .id             = _id,                          \
605                 .branch_type    = branch_divider,               \
606                 .name           = cname,                        \
607                 .parent_names   = (const char *[]){ pname },    \
608                 .num_parents    = 1,                            \
609                 .flags          = f,                            \
610                 .muxdiv_offset  = o,                            \
611                 .div_shift      = s,                            \
612                 .div_width      = w,                            \
613                 .div_flags      = df,                           \
614                 .div_table      = dt,                           \
615         }
616
617 #define GATE(_id, cname, pname, f, o, b, gf)                    \
618         {                                                       \
619                 .id             = _id,                          \
620                 .branch_type    = branch_gate,                  \
621                 .name           = cname,                        \
622                 .parent_names   = (const char *[]){ pname },    \
623                 .num_parents    = 1,                            \
624                 .flags          = f,                            \
625                 .gate_offset    = o,                            \
626                 .gate_shift     = b,                            \
627                 .gate_flags     = gf,                           \
628         }
629
630 #define MMC(_id, cname, pname, offset, shift)                   \
631         {                                                       \
632                 .id             = _id,                          \
633                 .branch_type    = branch_mmc,                   \
634                 .name           = cname,                        \
635                 .parent_names   = (const char *[]){ pname },    \
636                 .num_parents    = 1,                            \
637                 .muxdiv_offset  = offset,                       \
638                 .div_shift      = shift,                        \
639         }
640
641 #define INVERTER(_id, cname, pname, io, is, if)                 \
642         {                                                       \
643                 .id             = _id,                          \
644                 .branch_type    = branch_inverter,              \
645                 .name           = cname,                        \
646                 .parent_names   = (const char *[]){ pname },    \
647                 .num_parents    = 1,                            \
648                 .muxdiv_offset  = io,                           \
649                 .div_shift      = is,                           \
650                 .div_flags      = if,                           \
651         }
652
653 #define FACTOR(_id, cname, pname,  f, fm, fd)                   \
654         {                                                       \
655                 .id             = _id,                          \
656                 .branch_type    = branch_factor,                \
657                 .name           = cname,                        \
658                 .parent_names   = (const char *[]){ pname },    \
659                 .num_parents    = 1,                            \
660                 .flags          = f,                            \
661                 .div_shift      = fm,                           \
662                 .div_width      = fd,                           \
663         }
664
665 #define FACTOR_GATE(_id, cname, pname,  f, fm, fd, go, gb, gf)  \
666         {                                                       \
667                 .id             = _id,                          \
668                 .branch_type    = branch_factor,                \
669                 .name           = cname,                        \
670                 .parent_names   = (const char *[]){ pname },    \
671                 .num_parents    = 1,                            \
672                 .flags          = f,                            \
673                 .div_shift      = fm,                           \
674                 .div_width      = fd,                           \
675                 .gate_offset    = go,                           \
676                 .gate_shift     = gb,                           \
677                 .gate_flags     = gf,                           \
678         }
679
680 struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np,
681                         void __iomem *base, unsigned long nr_clks);
682 void rockchip_clk_of_add_provider(struct device_node *np,
683                                 struct rockchip_clk_provider *ctx);
684 struct regmap *rockchip_clk_get_grf(struct rockchip_clk_provider *ctx);
685 void rockchip_clk_add_lookup(struct rockchip_clk_provider *ctx,
686                              struct clk *clk, unsigned int id);
687 void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
688                                     struct rockchip_clk_branch *list,
689                                     unsigned int nr_clk);
690 void rockchip_clk_register_plls(struct rockchip_clk_provider *ctx,
691                                 struct rockchip_pll_clock *pll_list,
692                                 unsigned int nr_pll, int grf_lock_offset);
693 void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx,
694                         unsigned int lookup_id, const char *name,
695                         const char *const *parent_names, u8 num_parents,
696                         const struct rockchip_cpuclk_reg_data *reg_data,
697                         const struct rockchip_cpuclk_rate_table *rates,
698                         int nrates);
699 void rockchip_clk_protect_critical(const char *const clocks[], int nclocks);
700 void rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx,
701                                         unsigned int reg, void (*cb)(void));
702
703 #define ROCKCHIP_SOFTRST_HIWORD_MASK    BIT(0)
704
705 #ifdef CONFIG_RESET_CONTROLLER
706 void rockchip_register_softrst(struct device_node *np,
707                                unsigned int num_regs,
708                                void __iomem *base, u8 flags);
709 #else
710 static inline void rockchip_register_softrst(struct device_node *np,
711                                unsigned int num_regs,
712                                void __iomem *base, u8 flags)
713 {
714 }
715 #endif
716
717 #endif