1
2
3
4
5
6
7
8
9
10
11
12
13#ifndef __SAMSUNG_CLK_H
14#define __SAMSUNG_CLK_H
15
16#include <linux/clk.h>
17#include <linux/clkdev.h>
18#include <linux/io.h>
19#include <linux/clk-provider.h>
20#include <linux/of.h>
21#include <linux/of_address.h>
22#include "clk-pll.h"
23
24
25
26
27
28
29
30struct samsung_clk_provider {
31 void __iomem *reg_base;
32 struct clk_onecell_data clk_data;
33 spinlock_t lock;
34};
35
36
37
38
39
40
41
42struct samsung_clock_alias {
43 unsigned int id;
44 const char *dev_name;
45 const char *alias;
46};
47
48#define ALIAS(_id, dname, a) \
49 { \
50 .id = _id, \
51 .dev_name = dname, \
52 .alias = a, \
53 }
54
55#define MHZ (1000 * 1000)
56
57
58
59
60
61
62
63
64
65struct samsung_fixed_rate_clock {
66 unsigned int id;
67 char *name;
68 const char *parent_name;
69 unsigned long flags;
70 unsigned long fixed_rate;
71};
72
73#define FRATE(_id, cname, pname, f, frate) \
74 { \
75 .id = _id, \
76 .name = cname, \
77 .parent_name = pname, \
78 .flags = f, \
79 .fixed_rate = frate, \
80 }
81
82
83
84
85
86
87
88
89
90
91struct samsung_fixed_factor_clock {
92 unsigned int id;
93 char *name;
94 const char *parent_name;
95 unsigned long mult;
96 unsigned long div;
97 unsigned long flags;
98};
99
100#define FFACTOR(_id, cname, pname, m, d, f) \
101 { \
102 .id = _id, \
103 .name = cname, \
104 .parent_name = pname, \
105 .mult = m, \
106 .div = d, \
107 .flags = f, \
108 }
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124struct samsung_mux_clock {
125 unsigned int id;
126 const char *dev_name;
127 const char *name;
128 const char **parent_names;
129 u8 num_parents;
130 unsigned long flags;
131 unsigned long offset;
132 u8 shift;
133 u8 width;
134 u8 mux_flags;
135 const char *alias;
136};
137
138#define __MUX(_id, dname, cname, pnames, o, s, w, f, mf, a) \
139 { \
140 .id = _id, \
141 .dev_name = dname, \
142 .name = cname, \
143 .parent_names = pnames, \
144 .num_parents = ARRAY_SIZE(pnames), \
145 .flags = (f) | CLK_SET_RATE_NO_REPARENT, \
146 .offset = o, \
147 .shift = s, \
148 .width = w, \
149 .mux_flags = mf, \
150 .alias = a, \
151 }
152
153#define MUX(_id, cname, pnames, o, s, w) \
154 __MUX(_id, NULL, cname, pnames, o, s, w, 0, 0, NULL)
155
156#define MUX_A(_id, cname, pnames, o, s, w, a) \
157 __MUX(_id, NULL, cname, pnames, o, s, w, 0, 0, a)
158
159#define MUX_F(_id, cname, pnames, o, s, w, f, mf) \
160 __MUX(_id, NULL, cname, pnames, o, s, w, f, mf, NULL)
161
162#define MUX_FA(_id, cname, pnames, o, s, w, f, mf, a) \
163 __MUX(_id, NULL, cname, pnames, o, s, w, f, mf, a)
164
165
166
167
168
169
170
171
172
173
174
175
176
177struct samsung_div_clock {
178 unsigned int id;
179 const char *dev_name;
180 const char *name;
181 const char *parent_name;
182 unsigned long flags;
183 unsigned long offset;
184 u8 shift;
185 u8 width;
186 u8 div_flags;
187 const char *alias;
188 struct clk_div_table *table;
189};
190
191#define __DIV(_id, dname, cname, pname, o, s, w, f, df, a, t) \
192 { \
193 .id = _id, \
194 .dev_name = dname, \
195 .name = cname, \
196 .parent_name = pname, \
197 .flags = f, \
198 .offset = o, \
199 .shift = s, \
200 .width = w, \
201 .div_flags = df, \
202 .alias = a, \
203 .table = t, \
204 }
205
206#define DIV(_id, cname, pname, o, s, w) \
207 __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, NULL, NULL)
208
209#define DIV_A(_id, cname, pname, o, s, w, a) \
210 __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, a, NULL)
211
212#define DIV_F(_id, cname, pname, o, s, w, f, df) \
213 __DIV(_id, NULL, cname, pname, o, s, w, f, df, NULL, NULL)
214
215#define DIV_T(_id, cname, pname, o, s, w, t) \
216 __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, NULL, t)
217
218
219
220
221
222
223
224
225
226
227
228
229
230struct samsung_gate_clock {
231 unsigned int id;
232 const char *dev_name;
233 const char *name;
234 const char *parent_name;
235 unsigned long flags;
236 unsigned long offset;
237 u8 bit_idx;
238 u8 gate_flags;
239 const char *alias;
240};
241
242#define __GATE(_id, dname, cname, pname, o, b, f, gf, a) \
243 { \
244 .id = _id, \
245 .dev_name = dname, \
246 .name = cname, \
247 .parent_name = pname, \
248 .flags = f, \
249 .offset = o, \
250 .bit_idx = b, \
251 .gate_flags = gf, \
252 .alias = a, \
253 }
254
255#define GATE(_id, cname, pname, o, b, f, gf) \
256 __GATE(_id, NULL, cname, pname, o, b, f, gf, NULL)
257
258#define GATE_A(_id, cname, pname, o, b, f, gf, a) \
259 __GATE(_id, NULL, cname, pname, o, b, f, gf, a)
260
261#define GATE_D(_id, dname, cname, pname, o, b, f, gf) \
262 __GATE(_id, dname, cname, pname, o, b, f, gf, NULL)
263
264#define GATE_DA(_id, dname, cname, pname, o, b, f, gf, a) \
265 __GATE(_id, dname, cname, pname, o, b, f, gf, a)
266
267#define PNAME(x) static const char *x[] __initdata
268
269
270
271
272
273
274struct samsung_clk_reg_dump {
275 u32 offset;
276 u32 value;
277};
278
279
280
281
282
283
284
285
286
287
288
289
290
291struct samsung_pll_clock {
292 unsigned int id;
293 const char *dev_name;
294 const char *name;
295 const char *parent_name;
296 unsigned long flags;
297 int con_offset;
298 int lock_offset;
299 enum samsung_pll_type type;
300 const struct samsung_pll_rate_table *rate_table;
301 const char *alias;
302};
303
304#define __PLL(_typ, _id, _dname, _name, _pname, _flags, _lock, _con, \
305 _rtable, _alias) \
306 { \
307 .id = _id, \
308 .type = _typ, \
309 .dev_name = _dname, \
310 .name = _name, \
311 .parent_name = _pname, \
312 .flags = CLK_GET_RATE_NOCACHE, \
313 .con_offset = _con, \
314 .lock_offset = _lock, \
315 .rate_table = _rtable, \
316 .alias = _alias, \
317 }
318
319#define PLL(_typ, _id, _name, _pname, _lock, _con, _rtable) \
320 __PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE, \
321 _lock, _con, _rtable, _name)
322
323#define PLL_A(_typ, _id, _name, _pname, _lock, _con, _alias, _rtable) \
324 __PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE, \
325 _lock, _con, _rtable, _alias)
326
327extern struct samsung_clk_provider *__init samsung_clk_init(
328 struct device_node *np, void __iomem *base,
329 unsigned long nr_clks);
330extern void __init samsung_clk_of_add_provider(struct device_node *np,
331 struct samsung_clk_provider *ctx);
332extern void __init samsung_clk_of_register_fixed_ext(
333 struct samsung_clk_provider *ctx,
334 struct samsung_fixed_rate_clock *fixed_rate_clk,
335 unsigned int nr_fixed_rate_clk,
336 const struct of_device_id *clk_matches);
337
338extern void samsung_clk_add_lookup(struct samsung_clk_provider *ctx,
339 struct clk *clk, unsigned int id);
340
341extern void samsung_clk_register_alias(struct samsung_clk_provider *ctx,
342 struct samsung_clock_alias *list,
343 unsigned int nr_clk);
344extern void __init samsung_clk_register_fixed_rate(
345 struct samsung_clk_provider *ctx,
346 struct samsung_fixed_rate_clock *clk_list,
347 unsigned int nr_clk);
348extern void __init samsung_clk_register_fixed_factor(
349 struct samsung_clk_provider *ctx,
350 struct samsung_fixed_factor_clock *list,
351 unsigned int nr_clk);
352extern void __init samsung_clk_register_mux(struct samsung_clk_provider *ctx,
353 struct samsung_mux_clock *clk_list,
354 unsigned int nr_clk);
355extern void __init samsung_clk_register_div(struct samsung_clk_provider *ctx,
356 struct samsung_div_clock *clk_list,
357 unsigned int nr_clk);
358extern void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx,
359 struct samsung_gate_clock *clk_list,
360 unsigned int nr_clk);
361extern void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx,
362 struct samsung_pll_clock *pll_list,
363 unsigned int nr_clk, void __iomem *base);
364
365extern unsigned long _get_rate(const char *clk_name);
366
367extern void samsung_clk_save(void __iomem *base,
368 struct samsung_clk_reg_dump *rd,
369 unsigned int num_regs);
370extern void samsung_clk_restore(void __iomem *base,
371 const struct samsung_clk_reg_dump *rd,
372 unsigned int num_regs);
373extern struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump(
374 const unsigned long *rdump,
375 unsigned long nr_rdump);
376
377#endif
378