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