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