Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux...
[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  * based on
6  *
7  * samsung/clk.h
8  * Copyright (c) 2013 Samsung Electronics Co., Ltd.
9  * Copyright (c) 2013 Linaro Ltd.
10  * Author: Thomas Abraham <thomas.ab@samsung.com>
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  */
22
23 #ifndef CLK_ROCKCHIP_CLK_H
24 #define CLK_ROCKCHIP_CLK_H
25
26 #include <linux/io.h>
27
28 struct clk;
29
30 #define HIWORD_UPDATE(val, mask, shift) \
31                 ((val) << (shift) | (mask) << ((shift) + 16))
32
33 /* register positions shared by RK2928, RK3066 and RK3188 */
34 #define RK2928_PLL_CON(x)               ((x) * 0x4)
35 #define RK2928_MODE_CON         0x40
36 #define RK2928_CLKSEL_CON(x)    ((x) * 0x4 + 0x44)
37 #define RK2928_CLKGATE_CON(x)   ((x) * 0x4 + 0xd0)
38 #define RK2928_GLB_SRST_FST             0x100
39 #define RK2928_GLB_SRST_SND             0x104
40 #define RK2928_SOFTRST_CON(x)   ((x) * 0x4 + 0x110)
41 #define RK2928_MISC_CON         0x134
42
43 #define RK3288_PLL_CON(x)               RK2928_PLL_CON(x)
44 #define RK3288_MODE_CON                 0x50
45 #define RK3288_CLKSEL_CON(x)            ((x) * 0x4 + 0x60)
46 #define RK3288_CLKGATE_CON(x)           ((x) * 0x4 + 0x160)
47 #define RK3288_GLB_SRST_FST             0x1b0
48 #define RK3288_GLB_SRST_SND             0x1b4
49 #define RK3288_SOFTRST_CON(x)           ((x) * 0x4 + 0x1b8)
50 #define RK3288_MISC_CON                 0x1e8
51 #define RK3288_SDMMC_CON0               0x200
52 #define RK3288_SDMMC_CON1               0x204
53 #define RK3288_SDIO0_CON0               0x208
54 #define RK3288_SDIO0_CON1               0x20c
55 #define RK3288_SDIO1_CON0               0x210
56 #define RK3288_SDIO1_CON1               0x214
57 #define RK3288_EMMC_CON0                0x218
58 #define RK3288_EMMC_CON1                0x21c
59
60 #define RK3368_PLL_CON(x)               RK2928_PLL_CON(x)
61 #define RK3368_CLKSEL_CON(x)            ((x) * 0x4 + 0x100)
62 #define RK3368_CLKGATE_CON(x)           ((x) * 0x4 + 0x200)
63 #define RK3368_GLB_SRST_FST             0x280
64 #define RK3368_GLB_SRST_SND             0x284
65 #define RK3368_SOFTRST_CON(x)           ((x) * 0x4 + 0x300)
66 #define RK3368_MISC_CON                 0x380
67 #define RK3368_SDMMC_CON0               0x400
68 #define RK3368_SDMMC_CON1               0x404
69 #define RK3368_SDIO0_CON0               0x408
70 #define RK3368_SDIO0_CON1               0x40c
71 #define RK3368_SDIO1_CON0               0x410
72 #define RK3368_SDIO1_CON1               0x414
73 #define RK3368_EMMC_CON0                0x418
74 #define RK3368_EMMC_CON1                0x41c
75
76 enum rockchip_pll_type {
77         pll_rk3066,
78 };
79
80 #define RK3066_PLL_RATE(_rate, _nr, _nf, _no)   \
81 {                                               \
82         .rate   = _rate##U,                     \
83         .nr = _nr,                              \
84         .nf = _nf,                              \
85         .no = _no,                              \
86         .nb = ((_nf) < 2) ? 1 : (_nf) >> 1,     \
87 }
88
89 #define RK3066_PLL_RATE_NB(_rate, _nr, _nf, _no, _nb)           \
90 {                                                               \
91         .rate   = _rate##U,                                     \
92         .nr = _nr,                                              \
93         .nf = _nf,                                              \
94         .no = _no,                                              \
95         .nb = _nb,                                              \
96 }
97
98 struct rockchip_pll_rate_table {
99         unsigned long rate;
100         unsigned int nr;
101         unsigned int nf;
102         unsigned int no;
103         unsigned int nb;
104 };
105
106 /**
107  * struct rockchip_pll_clock: information about pll clock
108  * @id: platform specific id of the clock.
109  * @name: name of this pll clock.
110  * @parent_name: name of the parent clock.
111  * @flags: optional flags for basic clock.
112  * @con_offset: offset of the register for configuring the PLL.
113  * @mode_offset: offset of the register for configuring the PLL-mode.
114  * @mode_shift: offset inside the mode-register for the mode of this pll.
115  * @lock_shift: offset inside the lock register for the lock status.
116  * @type: Type of PLL to be registered.
117  * @pll_flags: hardware-specific flags
118  * @rate_table: Table of usable pll rates
119  *
120  * Flags:
121  * ROCKCHIP_PLL_SYNC_RATE - check rate parameters to match against the
122  *      rate_table parameters and ajust them if necessary.
123  */
124 struct rockchip_pll_clock {
125         unsigned int            id;
126         const char              *name;
127         const char              *const *parent_names;
128         u8                      num_parents;
129         unsigned long           flags;
130         int                     con_offset;
131         int                     mode_offset;
132         int                     mode_shift;
133         int                     lock_shift;
134         enum rockchip_pll_type  type;
135         u8                      pll_flags;
136         struct rockchip_pll_rate_table *rate_table;
137 };
138
139 #define ROCKCHIP_PLL_SYNC_RATE          BIT(0)
140
141 #define PLL(_type, _id, _name, _pnames, _flags, _con, _mode, _mshift,   \
142                 _lshift, _pflags, _rtable)                              \
143         {                                                               \
144                 .id             = _id,                                  \
145                 .type           = _type,                                \
146                 .name           = _name,                                \
147                 .parent_names   = _pnames,                              \
148                 .num_parents    = ARRAY_SIZE(_pnames),                  \
149                 .flags          = CLK_GET_RATE_NOCACHE | _flags,        \
150                 .con_offset     = _con,                                 \
151                 .mode_offset    = _mode,                                \
152                 .mode_shift     = _mshift,                              \
153                 .lock_shift     = _lshift,                              \
154                 .pll_flags      = _pflags,                              \
155                 .rate_table     = _rtable,                              \
156         }
157
158 struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
159                 const char *name, const char *const *parent_names,
160                 u8 num_parents, void __iomem *base, int con_offset,
161                 int grf_lock_offset, int lock_shift, int reg_mode,
162                 int mode_shift, struct rockchip_pll_rate_table *rate_table,
163                 u8 clk_pll_flags, spinlock_t *lock);
164
165 struct rockchip_cpuclk_clksel {
166         int reg;
167         u32 val;
168 };
169
170 #define ROCKCHIP_CPUCLK_NUM_DIVIDERS    2
171 struct rockchip_cpuclk_rate_table {
172         unsigned long prate;
173         struct rockchip_cpuclk_clksel divs[ROCKCHIP_CPUCLK_NUM_DIVIDERS];
174 };
175
176 /**
177  * struct rockchip_cpuclk_reg_data: describes register offsets and masks of the cpuclock
178  * @core_reg:           register offset of the core settings register
179  * @div_core_shift:     core divider offset used to divide the pll value
180  * @div_core_mask:      core divider mask
181  * @mux_core_shift:     offset of the core multiplexer
182  */
183 struct rockchip_cpuclk_reg_data {
184         int             core_reg;
185         u8              div_core_shift;
186         u32             div_core_mask;
187         int             mux_core_reg;
188         u8              mux_core_shift;
189 };
190
191 struct clk *rockchip_clk_register_cpuclk(const char *name,
192                         const char *const *parent_names, u8 num_parents,
193                         const struct rockchip_cpuclk_reg_data *reg_data,
194                         const struct rockchip_cpuclk_rate_table *rates,
195                         int nrates, void __iomem *reg_base, spinlock_t *lock);
196
197 struct clk *rockchip_clk_register_mmc(const char *name,
198                                 const char *const *parent_names, u8 num_parents,
199                                 void __iomem *reg, int shift);
200
201 #define ROCKCHIP_INVERTER_HIWORD_MASK   BIT(0)
202
203 struct clk *rockchip_clk_register_inverter(const char *name,
204                                 const char *const *parent_names, u8 num_parents,
205                                 void __iomem *reg, int shift, int flags,
206                                 spinlock_t *lock);
207
208 #define PNAME(x) static const char *const x[] __initconst
209
210 enum rockchip_clk_branch_type {
211         branch_composite,
212         branch_mux,
213         branch_divider,
214         branch_fraction_divider,
215         branch_gate,
216         branch_mmc,
217         branch_inverter,
218 };
219
220 struct rockchip_clk_branch {
221         unsigned int                    id;
222         enum rockchip_clk_branch_type   branch_type;
223         const char                      *name;
224         const char                      *const *parent_names;
225         u8                              num_parents;
226         unsigned long                   flags;
227         int                             muxdiv_offset;
228         u8                              mux_shift;
229         u8                              mux_width;
230         u8                              mux_flags;
231         u8                              div_shift;
232         u8                              div_width;
233         u8                              div_flags;
234         struct clk_div_table            *div_table;
235         int                             gate_offset;
236         u8                              gate_shift;
237         u8                              gate_flags;
238 };
239
240 #define COMPOSITE(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw,\
241                   df, go, gs, gf)                               \
242         {                                                       \
243                 .id             = _id,                          \
244                 .branch_type    = branch_composite,             \
245                 .name           = cname,                        \
246                 .parent_names   = pnames,                       \
247                 .num_parents    = ARRAY_SIZE(pnames),           \
248                 .flags          = f,                            \
249                 .muxdiv_offset  = mo,                           \
250                 .mux_shift      = ms,                           \
251                 .mux_width      = mw,                           \
252                 .mux_flags      = mf,                           \
253                 .div_shift      = ds,                           \
254                 .div_width      = dw,                           \
255                 .div_flags      = df,                           \
256                 .gate_offset    = go,                           \
257                 .gate_shift     = gs,                           \
258                 .gate_flags     = gf,                           \
259         }
260
261 #define COMPOSITE_NOMUX(_id, cname, pname, f, mo, ds, dw, df,   \
262                         go, gs, gf)                             \
263         {                                                       \
264                 .id             = _id,                          \
265                 .branch_type    = branch_composite,             \
266                 .name           = cname,                        \
267                 .parent_names   = (const char *[]){ pname },    \
268                 .num_parents    = 1,                            \
269                 .flags          = f,                            \
270                 .muxdiv_offset  = mo,                           \
271                 .div_shift      = ds,                           \
272                 .div_width      = dw,                           \
273                 .div_flags      = df,                           \
274                 .gate_offset    = go,                           \
275                 .gate_shift     = gs,                           \
276                 .gate_flags     = gf,                           \
277         }
278
279 #define COMPOSITE_NOMUX_DIVTBL(_id, cname, pname, f, mo, ds, dw,\
280                                df, dt, go, gs, gf)              \
281         {                                                       \
282                 .id             = _id,                          \
283                 .branch_type    = branch_composite,             \
284                 .name           = cname,                        \
285                 .parent_names   = (const char *[]){ pname },    \
286                 .num_parents    = 1,                            \
287                 .flags          = f,                            \
288                 .muxdiv_offset  = mo,                           \
289                 .div_shift      = ds,                           \
290                 .div_width      = dw,                           \
291                 .div_flags      = df,                           \
292                 .div_table      = dt,                           \
293                 .gate_offset    = go,                           \
294                 .gate_shift     = gs,                           \
295                 .gate_flags     = gf,                           \
296         }
297
298 #define COMPOSITE_NODIV(_id, cname, pnames, f, mo, ms, mw, mf,  \
299                         go, gs, gf)                             \
300         {                                                       \
301                 .id             = _id,                          \
302                 .branch_type    = branch_composite,             \
303                 .name           = cname,                        \
304                 .parent_names   = pnames,                       \
305                 .num_parents    = ARRAY_SIZE(pnames),           \
306                 .flags          = f,                            \
307                 .muxdiv_offset  = mo,                           \
308                 .mux_shift      = ms,                           \
309                 .mux_width      = mw,                           \
310                 .mux_flags      = mf,                           \
311                 .gate_offset    = go,                           \
312                 .gate_shift     = gs,                           \
313                 .gate_flags     = gf,                           \
314         }
315
316 #define COMPOSITE_NOGATE(_id, cname, pnames, f, mo, ms, mw, mf, \
317                          ds, dw, df)                            \
318         {                                                       \
319                 .id             = _id,                          \
320                 .branch_type    = branch_composite,             \
321                 .name           = cname,                        \
322                 .parent_names   = pnames,                       \
323                 .num_parents    = ARRAY_SIZE(pnames),           \
324                 .flags          = f,                            \
325                 .muxdiv_offset  = mo,                           \
326                 .mux_shift      = ms,                           \
327                 .mux_width      = mw,                           \
328                 .mux_flags      = mf,                           \
329                 .div_shift      = ds,                           \
330                 .div_width      = dw,                           \
331                 .div_flags      = df,                           \
332                 .gate_offset    = -1,                           \
333         }
334
335 #define COMPOSITE_NOGATE_DIVTBL(_id, cname, pnames, f, mo, ms,  \
336                                 mw, mf, ds, dw, df, dt)         \
337         {                                                       \
338                 .id             = _id,                          \
339                 .branch_type    = branch_composite,             \
340                 .name           = cname,                        \
341                 .parent_names   = pnames,                       \
342                 .num_parents    = ARRAY_SIZE(pnames),           \
343                 .flags          = f,                            \
344                 .muxdiv_offset  = mo,                           \
345                 .mux_shift      = ms,                           \
346                 .mux_width      = mw,                           \
347                 .mux_flags      = mf,                           \
348                 .div_shift      = ds,                           \
349                 .div_width      = dw,                           \
350                 .div_flags      = df,                           \
351                 .div_table      = dt,                           \
352                 .gate_offset    = -1,                           \
353         }
354
355 #define COMPOSITE_FRAC(_id, cname, pname, f, mo, df, go, gs, gf)\
356         {                                                       \
357                 .id             = _id,                          \
358                 .branch_type    = branch_fraction_divider,      \
359                 .name           = cname,                        \
360                 .parent_names   = (const char *[]){ pname },    \
361                 .num_parents    = 1,                            \
362                 .flags          = f,                            \
363                 .muxdiv_offset  = mo,                           \
364                 .div_shift      = 16,                           \
365                 .div_width      = 16,                           \
366                 .div_flags      = df,                           \
367                 .gate_offset    = go,                           \
368                 .gate_shift     = gs,                           \
369                 .gate_flags     = gf,                           \
370         }
371
372 #define MUX(_id, cname, pnames, f, o, s, w, mf)                 \
373         {                                                       \
374                 .id             = _id,                          \
375                 .branch_type    = branch_mux,                   \
376                 .name           = cname,                        \
377                 .parent_names   = pnames,                       \
378                 .num_parents    = ARRAY_SIZE(pnames),           \
379                 .flags          = f,                            \
380                 .muxdiv_offset  = o,                            \
381                 .mux_shift      = s,                            \
382                 .mux_width      = w,                            \
383                 .mux_flags      = mf,                           \
384                 .gate_offset    = -1,                           \
385         }
386
387 #define DIV(_id, cname, pname, f, o, s, w, df)                  \
388         {                                                       \
389                 .id             = _id,                          \
390                 .branch_type    = branch_divider,               \
391                 .name           = cname,                        \
392                 .parent_names   = (const char *[]){ pname },    \
393                 .num_parents    = 1,                            \
394                 .flags          = f,                            \
395                 .muxdiv_offset  = o,                            \
396                 .div_shift      = s,                            \
397                 .div_width      = w,                            \
398                 .div_flags      = df,                           \
399                 .gate_offset    = -1,                           \
400         }
401
402 #define DIVTBL(_id, cname, pname, f, o, s, w, df, dt)           \
403         {                                                       \
404                 .id             = _id,                          \
405                 .branch_type    = branch_divider,               \
406                 .name           = cname,                        \
407                 .parent_names   = (const char *[]){ pname },    \
408                 .num_parents    = 1,                            \
409                 .flags          = f,                            \
410                 .muxdiv_offset  = o,                            \
411                 .div_shift      = s,                            \
412                 .div_width      = w,                            \
413                 .div_flags      = df,                           \
414                 .div_table      = dt,                           \
415         }
416
417 #define GATE(_id, cname, pname, f, o, b, gf)                    \
418         {                                                       \
419                 .id             = _id,                          \
420                 .branch_type    = branch_gate,                  \
421                 .name           = cname,                        \
422                 .parent_names   = (const char *[]){ pname },    \
423                 .num_parents    = 1,                            \
424                 .flags          = f,                            \
425                 .gate_offset    = o,                            \
426                 .gate_shift     = b,                            \
427                 .gate_flags     = gf,                           \
428         }
429
430 #define MMC(_id, cname, pname, offset, shift)                   \
431         {                                                       \
432                 .id             = _id,                          \
433                 .branch_type    = branch_mmc,                   \
434                 .name           = cname,                        \
435                 .parent_names   = (const char *[]){ pname },    \
436                 .num_parents    = 1,                            \
437                 .muxdiv_offset  = offset,                       \
438                 .div_shift      = shift,                        \
439         }
440
441 #define INVERTER(_id, cname, pname, io, is, if)                 \
442         {                                                       \
443                 .id             = _id,                          \
444                 .branch_type    = branch_inverter,              \
445                 .name           = cname,                        \
446                 .parent_names   = (const char *[]){ pname },    \
447                 .num_parents    = 1,                            \
448                 .muxdiv_offset  = io,                           \
449                 .div_shift      = is,                           \
450                 .div_flags      = if,                           \
451         }
452
453 void rockchip_clk_init(struct device_node *np, void __iomem *base,
454                        unsigned long nr_clks);
455 struct regmap *rockchip_clk_get_grf(void);
456 void rockchip_clk_add_lookup(struct clk *clk, unsigned int id);
457 void rockchip_clk_register_branches(struct rockchip_clk_branch *clk_list,
458                                     unsigned int nr_clk);
459 void rockchip_clk_register_plls(struct rockchip_pll_clock *pll_list,
460                                 unsigned int nr_pll, int grf_lock_offset);
461 void rockchip_clk_register_armclk(unsigned int lookup_id, const char *name,
462                         const char *const *parent_names, u8 num_parents,
463                         const struct rockchip_cpuclk_reg_data *reg_data,
464                         const struct rockchip_cpuclk_rate_table *rates,
465                         int nrates);
466 void rockchip_clk_protect_critical(const char *const clocks[], int nclocks);
467 void rockchip_register_restart_notifier(unsigned int reg);
468
469 #define ROCKCHIP_SOFTRST_HIWORD_MASK    BIT(0)
470
471 #ifdef CONFIG_RESET_CONTROLLER
472 void rockchip_register_softrst(struct device_node *np,
473                                unsigned int num_regs,
474                                void __iomem *base, u8 flags);
475 #else
476 static inline void rockchip_register_softrst(struct device_node *np,
477                                unsigned int num_regs,
478                                void __iomem *base, u8 flags)
479 {
480 }
481 #endif
482
483 #endif