]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/clk/rockchip/clk.h
Merge remote-tracking branch 'edac-amd/for-next'
[karo-tx-linux.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
31 struct clk;
32
33 #define HIWORD_UPDATE(val, mask, shift) \
34                 ((val) << (shift) | (mask) << ((shift) + 16))
35
36 /* register positions shared by RK2928, RK3036, RK3066, RK3188 and RK3228 */
37 #define RK2928_PLL_CON(x)               ((x) * 0x4)
38 #define RK2928_MODE_CON         0x40
39 #define RK2928_CLKSEL_CON(x)    ((x) * 0x4 + 0x44)
40 #define RK2928_CLKGATE_CON(x)   ((x) * 0x4 + 0xd0)
41 #define RK2928_GLB_SRST_FST             0x100
42 #define RK2928_GLB_SRST_SND             0x104
43 #define RK2928_SOFTRST_CON(x)   ((x) * 0x4 + 0x110)
44 #define RK2928_MISC_CON         0x134
45
46 #define RK3036_SDMMC_CON0               0x144
47 #define RK3036_SDMMC_CON1               0x148
48 #define RK3036_SDIO_CON0                0x14c
49 #define RK3036_SDIO_CON1                0x150
50 #define RK3036_EMMC_CON0                0x154
51 #define RK3036_EMMC_CON1                0x158
52
53 #define RK3228_GLB_SRST_FST             0x1f0
54 #define RK3228_GLB_SRST_SND             0x1f4
55 #define RK3228_SDMMC_CON0               0x1c0
56 #define RK3228_SDMMC_CON1               0x1c4
57 #define RK3228_SDIO_CON0                0x1c8
58 #define RK3228_SDIO_CON1                0x1cc
59 #define RK3228_EMMC_CON0                0x1d8
60 #define RK3228_EMMC_CON1                0x1dc
61
62 #define RK3288_PLL_CON(x)               RK2928_PLL_CON(x)
63 #define RK3288_MODE_CON                 0x50
64 #define RK3288_CLKSEL_CON(x)            ((x) * 0x4 + 0x60)
65 #define RK3288_CLKGATE_CON(x)           ((x) * 0x4 + 0x160)
66 #define RK3288_GLB_SRST_FST             0x1b0
67 #define RK3288_GLB_SRST_SND             0x1b4
68 #define RK3288_SOFTRST_CON(x)           ((x) * 0x4 + 0x1b8)
69 #define RK3288_MISC_CON                 0x1e8
70 #define RK3288_SDMMC_CON0               0x200
71 #define RK3288_SDMMC_CON1               0x204
72 #define RK3288_SDIO0_CON0               0x208
73 #define RK3288_SDIO0_CON1               0x20c
74 #define RK3288_SDIO1_CON0               0x210
75 #define RK3288_SDIO1_CON1               0x214
76 #define RK3288_EMMC_CON0                0x218
77 #define RK3288_EMMC_CON1                0x21c
78
79 #define RK3368_PLL_CON(x)               RK2928_PLL_CON(x)
80 #define RK3368_CLKSEL_CON(x)            ((x) * 0x4 + 0x100)
81 #define RK3368_CLKGATE_CON(x)           ((x) * 0x4 + 0x200)
82 #define RK3368_GLB_SRST_FST             0x280
83 #define RK3368_GLB_SRST_SND             0x284
84 #define RK3368_SOFTRST_CON(x)           ((x) * 0x4 + 0x300)
85 #define RK3368_MISC_CON                 0x380
86 #define RK3368_SDMMC_CON0               0x400
87 #define RK3368_SDMMC_CON1               0x404
88 #define RK3368_SDIO0_CON0               0x408
89 #define RK3368_SDIO0_CON1               0x40c
90 #define RK3368_SDIO1_CON0               0x410
91 #define RK3368_SDIO1_CON1               0x414
92 #define RK3368_EMMC_CON0                0x418
93 #define RK3368_EMMC_CON1                0x41c
94
95 enum rockchip_pll_type {
96         pll_rk3036,
97         pll_rk3066,
98 };
99
100 #define RK3036_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1,      \
101                         _postdiv2, _dsmpd, _frac)               \
102 {                                                               \
103         .rate   = _rate##U,                                     \
104         .fbdiv = _fbdiv,                                        \
105         .postdiv1 = _postdiv1,                                  \
106         .refdiv = _refdiv,                                      \
107         .postdiv2 = _postdiv2,                                  \
108         .dsmpd = _dsmpd,                                        \
109         .frac = _frac,                                          \
110 }
111
112 #define RK3066_PLL_RATE(_rate, _nr, _nf, _no)   \
113 {                                               \
114         .rate   = _rate##U,                     \
115         .nr = _nr,                              \
116         .nf = _nf,                              \
117         .no = _no,                              \
118         .nb = ((_nf) < 2) ? 1 : (_nf) >> 1,     \
119 }
120
121 #define RK3066_PLL_RATE_NB(_rate, _nr, _nf, _no, _nb)           \
122 {                                                               \
123         .rate   = _rate##U,                                     \
124         .nr = _nr,                                              \
125         .nf = _nf,                                              \
126         .no = _no,                                              \
127         .nb = _nb,                                              \
128 }
129
130 struct rockchip_pll_rate_table {
131         unsigned long rate;
132         unsigned int nr;
133         unsigned int nf;
134         unsigned int no;
135         unsigned int nb;
136         /* for RK3036 */
137         unsigned int fbdiv;
138         unsigned int postdiv1;
139         unsigned int refdiv;
140         unsigned int postdiv2;
141         unsigned int dsmpd;
142         unsigned int frac;
143 };
144
145 /**
146  * struct rockchip_pll_clock: information about pll clock
147  * @id: platform specific id of the clock.
148  * @name: name of this pll clock.
149  * @parent_name: name of the parent clock.
150  * @flags: optional flags for basic clock.
151  * @con_offset: offset of the register for configuring the PLL.
152  * @mode_offset: offset of the register for configuring the PLL-mode.
153  * @mode_shift: offset inside the mode-register for the mode of this pll.
154  * @lock_shift: offset inside the lock register for the lock status.
155  * @type: Type of PLL to be registered.
156  * @pll_flags: hardware-specific flags
157  * @rate_table: Table of usable pll rates
158  *
159  * Flags:
160  * ROCKCHIP_PLL_SYNC_RATE - check rate parameters to match against the
161  *      rate_table parameters and ajust them if necessary.
162  */
163 struct rockchip_pll_clock {
164         unsigned int            id;
165         const char              *name;
166         const char              *const *parent_names;
167         u8                      num_parents;
168         unsigned long           flags;
169         int                     con_offset;
170         int                     mode_offset;
171         int                     mode_shift;
172         int                     lock_shift;
173         enum rockchip_pll_type  type;
174         u8                      pll_flags;
175         struct rockchip_pll_rate_table *rate_table;
176 };
177
178 #define ROCKCHIP_PLL_SYNC_RATE          BIT(0)
179
180 #define PLL(_type, _id, _name, _pnames, _flags, _con, _mode, _mshift,   \
181                 _lshift, _pflags, _rtable)                              \
182         {                                                               \
183                 .id             = _id,                                  \
184                 .type           = _type,                                \
185                 .name           = _name,                                \
186                 .parent_names   = _pnames,                              \
187                 .num_parents    = ARRAY_SIZE(_pnames),                  \
188                 .flags          = CLK_GET_RATE_NOCACHE | _flags,        \
189                 .con_offset     = _con,                                 \
190                 .mode_offset    = _mode,                                \
191                 .mode_shift     = _mshift,                              \
192                 .lock_shift     = _lshift,                              \
193                 .pll_flags      = _pflags,                              \
194                 .rate_table     = _rtable,                              \
195         }
196
197 struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
198                 const char *name, const char *const *parent_names,
199                 u8 num_parents, void __iomem *base, int con_offset,
200                 int grf_lock_offset, int lock_shift, int reg_mode,
201                 int mode_shift, struct rockchip_pll_rate_table *rate_table,
202                 u8 clk_pll_flags, spinlock_t *lock);
203
204 struct rockchip_cpuclk_clksel {
205         int reg;
206         u32 val;
207 };
208
209 #define ROCKCHIP_CPUCLK_NUM_DIVIDERS    2
210 struct rockchip_cpuclk_rate_table {
211         unsigned long prate;
212         struct rockchip_cpuclk_clksel divs[ROCKCHIP_CPUCLK_NUM_DIVIDERS];
213 };
214
215 /**
216  * struct rockchip_cpuclk_reg_data: describes register offsets and masks of the cpuclock
217  * @core_reg:           register offset of the core settings register
218  * @div_core_shift:     core divider offset used to divide the pll value
219  * @div_core_mask:      core divider mask
220  * @mux_core_shift:     offset of the core multiplexer
221  */
222 struct rockchip_cpuclk_reg_data {
223         int             core_reg;
224         u8              div_core_shift;
225         u32             div_core_mask;
226         int             mux_core_reg;
227         u8              mux_core_shift;
228 };
229
230 struct clk *rockchip_clk_register_cpuclk(const char *name,
231                         const char *const *parent_names, u8 num_parents,
232                         const struct rockchip_cpuclk_reg_data *reg_data,
233                         const struct rockchip_cpuclk_rate_table *rates,
234                         int nrates, void __iomem *reg_base, spinlock_t *lock);
235
236 struct clk *rockchip_clk_register_mmc(const char *name,
237                                 const char *const *parent_names, u8 num_parents,
238                                 void __iomem *reg, int shift);
239
240 #define ROCKCHIP_INVERTER_HIWORD_MASK   BIT(0)
241
242 struct clk *rockchip_clk_register_inverter(const char *name,
243                                 const char *const *parent_names, u8 num_parents,
244                                 void __iomem *reg, int shift, int flags,
245                                 spinlock_t *lock);
246
247 #define PNAME(x) static const char *const x[] __initconst
248
249 enum rockchip_clk_branch_type {
250         branch_composite,
251         branch_mux,
252         branch_divider,
253         branch_fraction_divider,
254         branch_gate,
255         branch_mmc,
256         branch_inverter,
257         branch_factor,
258 };
259
260 struct rockchip_clk_branch {
261         unsigned int                    id;
262         enum rockchip_clk_branch_type   branch_type;
263         const char                      *name;
264         const char                      *const *parent_names;
265         u8                              num_parents;
266         unsigned long                   flags;
267         int                             muxdiv_offset;
268         u8                              mux_shift;
269         u8                              mux_width;
270         u8                              mux_flags;
271         u8                              div_shift;
272         u8                              div_width;
273         u8                              div_flags;
274         struct clk_div_table            *div_table;
275         int                             gate_offset;
276         u8                              gate_shift;
277         u8                              gate_flags;
278         struct rockchip_clk_branch      *child;
279 };
280
281 #define COMPOSITE(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw,\
282                   df, go, gs, gf)                               \
283         {                                                       \
284                 .id             = _id,                          \
285                 .branch_type    = branch_composite,             \
286                 .name           = cname,                        \
287                 .parent_names   = pnames,                       \
288                 .num_parents    = ARRAY_SIZE(pnames),           \
289                 .flags          = f,                            \
290                 .muxdiv_offset  = mo,                           \
291                 .mux_shift      = ms,                           \
292                 .mux_width      = mw,                           \
293                 .mux_flags      = mf,                           \
294                 .div_shift      = ds,                           \
295                 .div_width      = dw,                           \
296                 .div_flags      = df,                           \
297                 .gate_offset    = go,                           \
298                 .gate_shift     = gs,                           \
299                 .gate_flags     = gf,                           \
300         }
301
302 #define COMPOSITE_NOMUX(_id, cname, pname, f, mo, ds, dw, df,   \
303                         go, gs, gf)                             \
304         {                                                       \
305                 .id             = _id,                          \
306                 .branch_type    = branch_composite,             \
307                 .name           = cname,                        \
308                 .parent_names   = (const char *[]){ pname },    \
309                 .num_parents    = 1,                            \
310                 .flags          = f,                            \
311                 .muxdiv_offset  = mo,                           \
312                 .div_shift      = ds,                           \
313                 .div_width      = dw,                           \
314                 .div_flags      = df,                           \
315                 .gate_offset    = go,                           \
316                 .gate_shift     = gs,                           \
317                 .gate_flags     = gf,                           \
318         }
319
320 #define COMPOSITE_NOMUX_DIVTBL(_id, cname, pname, f, mo, ds, dw,\
321                                df, dt, go, gs, gf)              \
322         {                                                       \
323                 .id             = _id,                          \
324                 .branch_type    = branch_composite,             \
325                 .name           = cname,                        \
326                 .parent_names   = (const char *[]){ pname },    \
327                 .num_parents    = 1,                            \
328                 .flags          = f,                            \
329                 .muxdiv_offset  = mo,                           \
330                 .div_shift      = ds,                           \
331                 .div_width      = dw,                           \
332                 .div_flags      = df,                           \
333                 .div_table      = dt,                           \
334                 .gate_offset    = go,                           \
335                 .gate_shift     = gs,                           \
336                 .gate_flags     = gf,                           \
337         }
338
339 #define COMPOSITE_NODIV(_id, cname, pnames, f, mo, ms, mw, mf,  \
340                         go, gs, gf)                             \
341         {                                                       \
342                 .id             = _id,                          \
343                 .branch_type    = branch_composite,             \
344                 .name           = cname,                        \
345                 .parent_names   = pnames,                       \
346                 .num_parents    = ARRAY_SIZE(pnames),           \
347                 .flags          = f,                            \
348                 .muxdiv_offset  = mo,                           \
349                 .mux_shift      = ms,                           \
350                 .mux_width      = mw,                           \
351                 .mux_flags      = mf,                           \
352                 .gate_offset    = go,                           \
353                 .gate_shift     = gs,                           \
354                 .gate_flags     = gf,                           \
355         }
356
357 #define COMPOSITE_NOGATE(_id, cname, pnames, f, mo, ms, mw, mf, \
358                          ds, dw, df)                            \
359         {                                                       \
360                 .id             = _id,                          \
361                 .branch_type    = branch_composite,             \
362                 .name           = cname,                        \
363                 .parent_names   = pnames,                       \
364                 .num_parents    = ARRAY_SIZE(pnames),           \
365                 .flags          = f,                            \
366                 .muxdiv_offset  = mo,                           \
367                 .mux_shift      = ms,                           \
368                 .mux_width      = mw,                           \
369                 .mux_flags      = mf,                           \
370                 .div_shift      = ds,                           \
371                 .div_width      = dw,                           \
372                 .div_flags      = df,                           \
373                 .gate_offset    = -1,                           \
374         }
375
376 #define COMPOSITE_NOGATE_DIVTBL(_id, cname, pnames, f, mo, ms,  \
377                                 mw, mf, ds, dw, df, dt)         \
378         {                                                       \
379                 .id             = _id,                          \
380                 .branch_type    = branch_composite,             \
381                 .name           = cname,                        \
382                 .parent_names   = pnames,                       \
383                 .num_parents    = ARRAY_SIZE(pnames),           \
384                 .flags          = f,                            \
385                 .muxdiv_offset  = mo,                           \
386                 .mux_shift      = ms,                           \
387                 .mux_width      = mw,                           \
388                 .mux_flags      = mf,                           \
389                 .div_shift      = ds,                           \
390                 .div_width      = dw,                           \
391                 .div_flags      = df,                           \
392                 .div_table      = dt,                           \
393                 .gate_offset    = -1,                           \
394         }
395
396 #define COMPOSITE_FRAC(_id, cname, pname, f, mo, df, go, gs, gf)\
397         {                                                       \
398                 .id             = _id,                          \
399                 .branch_type    = branch_fraction_divider,      \
400                 .name           = cname,                        \
401                 .parent_names   = (const char *[]){ pname },    \
402                 .num_parents    = 1,                            \
403                 .flags          = f,                            \
404                 .muxdiv_offset  = mo,                           \
405                 .div_shift      = 16,                           \
406                 .div_width      = 16,                           \
407                 .div_flags      = df,                           \
408                 .gate_offset    = go,                           \
409                 .gate_shift     = gs,                           \
410                 .gate_flags     = gf,                           \
411         }
412
413 #define COMPOSITE_FRACMUX(_id, cname, pname, f, mo, df, go, gs, gf, ch) \
414         {                                                       \
415                 .id             = _id,                          \
416                 .branch_type    = branch_fraction_divider,      \
417                 .name           = cname,                        \
418                 .parent_names   = (const char *[]){ pname },    \
419                 .num_parents    = 1,                            \
420                 .flags          = f,                            \
421                 .muxdiv_offset  = mo,                           \
422                 .div_shift      = 16,                           \
423                 .div_width      = 16,                           \
424                 .div_flags      = df,                           \
425                 .gate_offset    = go,                           \
426                 .gate_shift     = gs,                           \
427                 .gate_flags     = gf,                           \
428                 .child          = ch,                           \
429         }
430
431 #define MUX(_id, cname, pnames, f, o, s, w, mf)                 \
432         {                                                       \
433                 .id             = _id,                          \
434                 .branch_type    = branch_mux,                   \
435                 .name           = cname,                        \
436                 .parent_names   = pnames,                       \
437                 .num_parents    = ARRAY_SIZE(pnames),           \
438                 .flags          = f,                            \
439                 .muxdiv_offset  = o,                            \
440                 .mux_shift      = s,                            \
441                 .mux_width      = w,                            \
442                 .mux_flags      = mf,                           \
443                 .gate_offset    = -1,                           \
444         }
445
446 #define DIV(_id, cname, pname, f, o, s, w, df)                  \
447         {                                                       \
448                 .id             = _id,                          \
449                 .branch_type    = branch_divider,               \
450                 .name           = cname,                        \
451                 .parent_names   = (const char *[]){ pname },    \
452                 .num_parents    = 1,                            \
453                 .flags          = f,                            \
454                 .muxdiv_offset  = o,                            \
455                 .div_shift      = s,                            \
456                 .div_width      = w,                            \
457                 .div_flags      = df,                           \
458                 .gate_offset    = -1,                           \
459         }
460
461 #define DIVTBL(_id, cname, pname, f, o, s, w, df, dt)           \
462         {                                                       \
463                 .id             = _id,                          \
464                 .branch_type    = branch_divider,               \
465                 .name           = cname,                        \
466                 .parent_names   = (const char *[]){ pname },    \
467                 .num_parents    = 1,                            \
468                 .flags          = f,                            \
469                 .muxdiv_offset  = o,                            \
470                 .div_shift      = s,                            \
471                 .div_width      = w,                            \
472                 .div_flags      = df,                           \
473                 .div_table      = dt,                           \
474         }
475
476 #define GATE(_id, cname, pname, f, o, b, gf)                    \
477         {                                                       \
478                 .id             = _id,                          \
479                 .branch_type    = branch_gate,                  \
480                 .name           = cname,                        \
481                 .parent_names   = (const char *[]){ pname },    \
482                 .num_parents    = 1,                            \
483                 .flags          = f,                            \
484                 .gate_offset    = o,                            \
485                 .gate_shift     = b,                            \
486                 .gate_flags     = gf,                           \
487         }
488
489 #define MMC(_id, cname, pname, offset, shift)                   \
490         {                                                       \
491                 .id             = _id,                          \
492                 .branch_type    = branch_mmc,                   \
493                 .name           = cname,                        \
494                 .parent_names   = (const char *[]){ pname },    \
495                 .num_parents    = 1,                            \
496                 .muxdiv_offset  = offset,                       \
497                 .div_shift      = shift,                        \
498         }
499
500 #define INVERTER(_id, cname, pname, io, is, if)                 \
501         {                                                       \
502                 .id             = _id,                          \
503                 .branch_type    = branch_inverter,              \
504                 .name           = cname,                        \
505                 .parent_names   = (const char *[]){ pname },    \
506                 .num_parents    = 1,                            \
507                 .muxdiv_offset  = io,                           \
508                 .div_shift      = is,                           \
509                 .div_flags      = if,                           \
510         }
511
512 #define FACTOR(_id, cname, pname,  f, fm, fd)                   \
513         {                                                       \
514                 .id             = _id,                          \
515                 .branch_type    = branch_factor,                \
516                 .name           = cname,                        \
517                 .parent_names   = (const char *[]){ pname },    \
518                 .num_parents    = 1,                            \
519                 .flags          = f,                            \
520                 .div_shift      = fm,                           \
521                 .div_width      = fd,                           \
522         }
523
524 #define FACTOR_GATE(_id, cname, pname,  f, fm, fd, go, gb, gf)  \
525         {                                                       \
526                 .id             = _id,                          \
527                 .branch_type    = branch_factor,                \
528                 .name           = cname,                        \
529                 .parent_names   = (const char *[]){ pname },    \
530                 .num_parents    = 1,                            \
531                 .flags          = f,                            \
532                 .div_shift      = fm,                           \
533                 .div_width      = fd,                           \
534                 .gate_offset    = go,                           \
535                 .gate_shift     = gb,                           \
536                 .gate_flags     = gf,                           \
537         }
538
539 void rockchip_clk_init(struct device_node *np, void __iomem *base,
540                        unsigned long nr_clks);
541 struct regmap *rockchip_clk_get_grf(void);
542 void rockchip_clk_add_lookup(struct clk *clk, unsigned int id);
543 void rockchip_clk_register_branches(struct rockchip_clk_branch *clk_list,
544                                     unsigned int nr_clk);
545 void rockchip_clk_register_plls(struct rockchip_pll_clock *pll_list,
546                                 unsigned int nr_pll, int grf_lock_offset);
547 void rockchip_clk_register_armclk(unsigned int lookup_id, const char *name,
548                         const char *const *parent_names, u8 num_parents,
549                         const struct rockchip_cpuclk_reg_data *reg_data,
550                         const struct rockchip_cpuclk_rate_table *rates,
551                         int nrates);
552 void rockchip_clk_protect_critical(const char *const clocks[], int nclocks);
553 void rockchip_register_restart_notifier(unsigned int reg, void (*cb)(void));
554
555 #define ROCKCHIP_SOFTRST_HIWORD_MASK    BIT(0)
556
557 #ifdef CONFIG_RESET_CONTROLLER
558 void rockchip_register_softrst(struct device_node *np,
559                                unsigned int num_regs,
560                                void __iomem *base, u8 flags);
561 #else
562 static inline void rockchip_register_softrst(struct device_node *np,
563                                unsigned int num_regs,
564                                void __iomem *base, u8 flags)
565 {
566 }
567 #endif
568
569 #endif