Merge branch 'x86-cpufeature-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[cascardo/linux.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 #include <linux/clk.h>
28 #include <linux/clk-provider.h>
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
52 enum rockchip_pll_type {
53         pll_rk3066,
54 };
55
56 #define RK3066_PLL_RATE(_rate, _nr, _nf, _no)   \
57 {                                               \
58         .rate   = _rate##U,                     \
59         .nr = _nr,                              \
60         .nf = _nf,                              \
61         .no = _no,                              \
62         .bwadj = (_nf >> 1),                    \
63 }
64
65 struct rockchip_pll_rate_table {
66         unsigned long rate;
67         unsigned int nr;
68         unsigned int nf;
69         unsigned int no;
70         unsigned int bwadj;
71 };
72
73 /**
74  * struct rockchip_pll_clock: information about pll clock
75  * @id: platform specific id of the clock.
76  * @name: name of this pll clock.
77  * @parent_name: name of the parent clock.
78  * @flags: optional flags for basic clock.
79  * @con_offset: offset of the register for configuring the PLL.
80  * @mode_offset: offset of the register for configuring the PLL-mode.
81  * @mode_shift: offset inside the mode-register for the mode of this pll.
82  * @lock_shift: offset inside the lock register for the lock status.
83  * @type: Type of PLL to be registered.
84  * @rate_table: Table of usable pll rates
85  */
86 struct rockchip_pll_clock {
87         unsigned int            id;
88         const char              *name;
89         const char              **parent_names;
90         u8                      num_parents;
91         unsigned long           flags;
92         int                     con_offset;
93         int                     mode_offset;
94         int                     mode_shift;
95         int                     lock_shift;
96         enum rockchip_pll_type  type;
97         struct rockchip_pll_rate_table *rate_table;
98 };
99
100 #define PLL(_type, _id, _name, _pnames, _flags, _con, _mode, _mshift,   \
101                 _lshift, _rtable)                                       \
102         {                                                               \
103                 .id             = _id,                                  \
104                 .type           = _type,                                \
105                 .name           = _name,                                \
106                 .parent_names   = _pnames,                              \
107                 .num_parents    = ARRAY_SIZE(_pnames),                  \
108                 .flags          = CLK_GET_RATE_NOCACHE | _flags,        \
109                 .con_offset     = _con,                                 \
110                 .mode_offset    = _mode,                                \
111                 .mode_shift     = _mshift,                              \
112                 .lock_shift     = _lshift,                              \
113                 .rate_table     = _rtable,                              \
114         }
115
116 struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
117                 const char *name, const char **parent_names, u8 num_parents,
118                 void __iomem *base, int con_offset, int grf_lock_offset,
119                 int lock_shift, int reg_mode, int mode_shift,
120                 struct rockchip_pll_rate_table *rate_table,
121                 spinlock_t *lock);
122
123 #define PNAME(x) static const char *x[] __initconst
124
125 enum rockchip_clk_branch_type {
126         branch_composite,
127         branch_mux,
128         branch_divider,
129         branch_fraction_divider,
130         branch_gate,
131 };
132
133 struct rockchip_clk_branch {
134         unsigned int                    id;
135         enum rockchip_clk_branch_type   branch_type;
136         const char                      *name;
137         const char                      **parent_names;
138         u8                              num_parents;
139         unsigned long                   flags;
140         int                             muxdiv_offset;
141         u8                              mux_shift;
142         u8                              mux_width;
143         u8                              mux_flags;
144         u8                              div_shift;
145         u8                              div_width;
146         u8                              div_flags;
147         struct clk_div_table            *div_table;
148         int                             gate_offset;
149         u8                              gate_shift;
150         u8                              gate_flags;
151 };
152
153 #define COMPOSITE(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw,\
154                   df, go, gs, gf)                               \
155         {                                                       \
156                 .id             = _id,                          \
157                 .branch_type    = branch_composite,             \
158                 .name           = cname,                        \
159                 .parent_names   = pnames,                       \
160                 .num_parents    = ARRAY_SIZE(pnames),           \
161                 .flags          = f,                            \
162                 .muxdiv_offset  = mo,                           \
163                 .mux_shift      = ms,                           \
164                 .mux_width      = mw,                           \
165                 .mux_flags      = mf,                           \
166                 .div_shift      = ds,                           \
167                 .div_width      = dw,                           \
168                 .div_flags      = df,                           \
169                 .gate_offset    = go,                           \
170                 .gate_shift     = gs,                           \
171                 .gate_flags     = gf,                           \
172         }
173
174 #define COMPOSITE_NOMUX(_id, cname, pname, f, mo, ds, dw, df,   \
175                         go, gs, gf)                             \
176         {                                                       \
177                 .id             = _id,                          \
178                 .branch_type    = branch_composite,             \
179                 .name           = cname,                        \
180                 .parent_names   = (const char *[]){ pname },    \
181                 .num_parents    = 1,                            \
182                 .flags          = f,                            \
183                 .muxdiv_offset  = mo,                           \
184                 .div_shift      = ds,                           \
185                 .div_width      = dw,                           \
186                 .div_flags      = df,                           \
187                 .gate_offset    = go,                           \
188                 .gate_shift     = gs,                           \
189                 .gate_flags     = gf,                           \
190         }
191
192 #define COMPOSITE_NOMUX_DIVTBL(_id, cname, pname, f, mo, ds, dw,\
193                                df, dt, go, gs, gf)              \
194         {                                                       \
195                 .id             = _id,                          \
196                 .branch_type    = branch_composite,             \
197                 .name           = cname,                        \
198                 .parent_names   = (const char *[]){ pname },    \
199                 .num_parents    = 1,                            \
200                 .flags          = f,                            \
201                 .muxdiv_offset  = mo,                           \
202                 .div_shift      = ds,                           \
203                 .div_width      = dw,                           \
204                 .div_flags      = df,                           \
205                 .div_table      = dt,                           \
206                 .gate_offset    = go,                           \
207                 .gate_shift     = gs,                           \
208                 .gate_flags     = gf,                           \
209         }
210
211 #define COMPOSITE_NODIV(_id, cname, pnames, f, mo, ms, mw, mf,  \
212                         go, gs, gf)                             \
213         {                                                       \
214                 .id             = _id,                          \
215                 .branch_type    = branch_composite,             \
216                 .name           = cname,                        \
217                 .parent_names   = pnames,                       \
218                 .num_parents    = ARRAY_SIZE(pnames),           \
219                 .flags          = f,                            \
220                 .muxdiv_offset  = mo,                           \
221                 .mux_shift      = ms,                           \
222                 .mux_width      = mw,                           \
223                 .mux_flags      = mf,                           \
224                 .gate_offset    = go,                           \
225                 .gate_shift     = gs,                           \
226                 .gate_flags     = gf,                           \
227         }
228
229 #define COMPOSITE_NOGATE(_id, cname, pnames, f, mo, ms, mw, mf, \
230                          ds, dw, df)                            \
231         {                                                       \
232                 .id             = _id,                          \
233                 .branch_type    = branch_composite,             \
234                 .name           = cname,                        \
235                 .parent_names   = pnames,                       \
236                 .num_parents    = ARRAY_SIZE(pnames),           \
237                 .flags          = f,                            \
238                 .muxdiv_offset  = mo,                           \
239                 .mux_shift      = ms,                           \
240                 .mux_width      = mw,                           \
241                 .mux_flags      = mf,                           \
242                 .div_shift      = ds,                           \
243                 .div_width      = dw,                           \
244                 .div_flags      = df,                           \
245                 .gate_offset    = -1,                           \
246         }
247
248 #define COMPOSITE_FRAC(_id, cname, pname, f, mo, df, go, gs, gf)\
249         {                                                       \
250                 .id             = _id,                          \
251                 .branch_type    = branch_fraction_divider,      \
252                 .name           = cname,                        \
253                 .parent_names   = (const char *[]){ pname },    \
254                 .num_parents    = 1,                            \
255                 .flags          = f,                            \
256                 .muxdiv_offset  = mo,                           \
257                 .div_shift      = 16,                           \
258                 .div_width      = 16,                           \
259                 .div_flags      = df,                           \
260                 .gate_offset    = go,                           \
261                 .gate_shift     = gs,                           \
262                 .gate_flags     = gf,                           \
263         }
264
265 #define MUX(_id, cname, pnames, f, o, s, w, mf)                 \
266         {                                                       \
267                 .id             = _id,                          \
268                 .branch_type    = branch_mux,                   \
269                 .name           = cname,                        \
270                 .parent_names   = pnames,                       \
271                 .num_parents    = ARRAY_SIZE(pnames),           \
272                 .flags          = f,                            \
273                 .muxdiv_offset  = o,                            \
274                 .mux_shift      = s,                            \
275                 .mux_width      = w,                            \
276                 .mux_flags      = mf,                           \
277                 .gate_offset    = -1,                           \
278         }
279
280 #define DIV(_id, cname, pname, f, o, s, w, df)                  \
281         {                                                       \
282                 .id             = _id,                          \
283                 .branch_type    = branch_divider,               \
284                 .name           = cname,                        \
285                 .parent_names   = (const char *[]){ pname },    \
286                 .num_parents    = 1,                            \
287                 .flags          = f,                            \
288                 .muxdiv_offset  = o,                            \
289                 .div_shift      = s,                            \
290                 .div_width      = w,                            \
291                 .div_flags      = df,                           \
292                 .gate_offset    = -1,                           \
293         }
294
295 #define DIVTBL(_id, cname, pname, f, o, s, w, df, dt)           \
296         {                                                       \
297                 .id             = _id,                          \
298                 .branch_type    = branch_divider,               \
299                 .name           = cname,                        \
300                 .parent_names   = (const char *[]){ pname },    \
301                 .num_parents    = 1,                            \
302                 .flags          = f,                            \
303                 .muxdiv_offset  = o,                            \
304                 .div_shift      = s,                            \
305                 .div_width      = w,                            \
306                 .div_flags      = df,                           \
307                 .div_table      = dt,                           \
308         }
309
310 #define GATE(_id, cname, pname, f, o, b, gf)                    \
311         {                                                       \
312                 .id             = _id,                          \
313                 .branch_type    = branch_gate,                  \
314                 .name           = cname,                        \
315                 .parent_names   = (const char *[]){ pname },    \
316                 .num_parents    = 1,                            \
317                 .flags          = f,                            \
318                 .gate_offset    = o,                            \
319                 .gate_shift     = b,                            \
320                 .gate_flags     = gf,                           \
321         }
322
323
324 void rockchip_clk_init(struct device_node *np, void __iomem *base,
325                        unsigned long nr_clks);
326 struct regmap *rockchip_clk_get_grf(void);
327 void rockchip_clk_add_lookup(struct clk *clk, unsigned int id);
328 void rockchip_clk_register_branches(struct rockchip_clk_branch *clk_list,
329                                     unsigned int nr_clk);
330 void rockchip_clk_register_plls(struct rockchip_pll_clock *pll_list,
331                                 unsigned int nr_pll, int grf_lock_offset);
332
333 #define ROCKCHIP_SOFTRST_HIWORD_MASK    BIT(0)
334
335 #ifdef CONFIG_RESET_CONTROLLER
336 void rockchip_register_softrst(struct device_node *np,
337                                unsigned int num_regs,
338                                void __iomem *base, u8 flags);
339 #else
340 static inline void rockchip_register_softrst(struct device_node *np,
341                                unsigned int num_regs,
342                                void __iomem *base, u8 flags)
343 {
344 }
345 #endif
346
347 #endif