1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3 * Copyright (c) 2013 Samsung Electronics Co., Ltd.
4 * Copyright (c) 2013 Linaro Ltd.
5 * Author: Thomas Abraham <thomas.ab@samsung.com>
6 *
7 * Common Clock Framework support for all Samsung platforms
8 */
9
10 #ifndef __SAMSUNG_CLK_H
11 #define __SAMSUNG_CLK_H
12
13 #include <linux/clk-provider.h>
14 #include "clk-pll.h"
15
16 /**
17 * struct samsung_clk_provider - information about clock provider
18 * @reg_base: virtual address for the register base
19 * @dev: clock provider device needed for runtime PM
20 * @lock: maintains exclusion between callbacks for a given clock-provider
21 * @clk_data: holds clock related data like clk_hw* and number of clocks
22 */
23 struct samsung_clk_provider {
24 void __iomem *reg_base;
25 struct device *dev;
26 spinlock_t lock;
27 /* clk_data must be the last entry due to variable length 'hws' array */
28 struct clk_hw_onecell_data clk_data;
29 };
30
31 /**
32 * struct samsung_clock_alias - information about mux clock
33 * @id: platform specific id of the clock
34 * @dev_name: name of the device to which this clock belongs
35 * @alias: optional clock alias name to be assigned to this clock
36 */
37 struct samsung_clock_alias {
38 unsigned int id;
39 const char *dev_name;
40 const char *alias;
41 };
42
43 #define ALIAS(_id, dname, a) \
44 { \
45 .id = _id, \
46 .dev_name = dname, \
47 .alias = a, \
48 }
49
50 #define MHZ (1000 * 1000)
51
52 /**
53 * struct samsung_fixed_rate_clock - information about fixed-rate clock
54 * @id: platform specific id of the clock
55 * @name: name of this fixed-rate clock
56 * @parent_name: optional parent clock name
57 * @flags: optional fixed-rate clock flags
58 * @fixed_rate: fixed clock rate of this clock
59 */
60 struct samsung_fixed_rate_clock {
61 unsigned int id;
62 char *name;
63 const char *parent_name;
64 unsigned long flags;
65 unsigned long fixed_rate;
66 };
67
68 #define FRATE(_id, cname, pname, f, frate) \
69 { \
70 .id = _id, \
71 .name = cname, \
72 .parent_name = pname, \
73 .flags = f, \
74 .fixed_rate = frate, \
75 }
76
77 /**
78 * struct samsung_fixed_factor_clock - information about fixed-factor clock
79 * @id: platform specific id of the clock
80 * @name: name of this fixed-factor clock
81 * @parent_name: parent clock name
82 * @mult: fixed multiplication factor
83 * @div: fixed division factor
84 * @flags: optional fixed-factor clock flags
85 */
86 struct samsung_fixed_factor_clock {
87 unsigned int id;
88 char *name;
89 const char *parent_name;
90 unsigned long mult;
91 unsigned long div;
92 unsigned long flags;
93 };
94
95 #define FFACTOR(_id, cname, pname, m, d, f) \
96 { \
97 .id = _id, \
98 .name = cname, \
99 .parent_name = pname, \
100 .mult = m, \
101 .div = d, \
102 .flags = f, \
103 }
104
105 /**
106 * struct samsung_mux_clock - information about mux clock
107 * @id: platform specific id of the clock
108 * @name: name of this mux clock
109 * @parent_names: array of pointer to parent clock names
110 * @num_parents: number of parents listed in @parent_names
111 * @flags: optional flags for basic clock
112 * @offset: offset of the register for configuring the mux
113 * @shift: starting bit location of the mux control bit-field in @reg
114 * @width: width of the mux control bit-field in @reg
115 * @mux_flags: flags for mux-type clock
116 */
117 struct samsung_mux_clock {
118 unsigned int id;
119 const char *name;
120 const char *const *parent_names;
121 u8 num_parents;
122 unsigned long flags;
123 unsigned long offset;
124 u8 shift;
125 u8 width;
126 u8 mux_flags;
127 };
128
129 #define __MUX(_id, cname, pnames, o, s, w, f, mf) \
130 { \
131 .id = _id, \
132 .name = cname, \
133 .parent_names = pnames, \
134 .num_parents = ARRAY_SIZE(pnames), \
135 .flags = (f) | CLK_SET_RATE_NO_REPARENT, \
136 .offset = o, \
137 .shift = s, \
138 .width = w, \
139 .mux_flags = mf, \
140 }
141
142 #define MUX(_id, cname, pnames, o, s, w) \
143 __MUX(_id, cname, pnames, o, s, w, 0, 0)
144
145 #define MUX_F(_id, cname, pnames, o, s, w, f, mf) \
146 __MUX(_id, cname, pnames, o, s, w, f, mf)
147
148 /**
149 * struct samsung_div_clock - information about div clock
150 * @id: platform specific id of the clock
151 * @name: name of this div clock
152 * @parent_name: name of the parent clock
153 * @flags: optional flags for basic clock
154 * @offset: offset of the register for configuring the div
155 * @shift: starting bit location of the div control bit-field in @reg
156 * @width: width of the bitfield
157 * @div_flags: flags for div-type clock
158 * @table: array of divider/value pairs ending with a div set to 0
159 */
160 struct samsung_div_clock {
161 unsigned int id;
162 const char *name;
163 const char *parent_name;
164 unsigned long flags;
165 unsigned long offset;
166 u8 shift;
167 u8 width;
168 u8 div_flags;
169 struct clk_div_table *table;
170 };
171
172 #define __DIV(_id, cname, pname, o, s, w, f, df, t) \
173 { \
174 .id = _id, \
175 .name = cname, \
176 .parent_name = pname, \
177 .flags = f, \
178 .offset = o, \
179 .shift = s, \
180 .width = w, \
181 .div_flags = df, \
182 .table = t, \
183 }
184
185 #define DIV(_id, cname, pname, o, s, w) \
186 __DIV(_id, cname, pname, o, s, w, 0, 0, NULL)
187
188 #define DIV_F(_id, cname, pname, o, s, w, f, df) \
189 __DIV(_id, cname, pname, o, s, w, f, df, NULL)
190
191 #define DIV_T(_id, cname, pname, o, s, w, t) \
192 __DIV(_id, cname, pname, o, s, w, 0, 0, t)
193
194 /**
195 * struct samsung_gate_clock - information about gate clock
196 * @id: platform specific id of the clock
197 * @name: name of this gate clock
198 * @parent_name: name of the parent clock
199 * @flags: optional flags for basic clock
200 * @offset: offset of the register for configuring the gate
201 * @bit_idx: bit index of the gate control bit-field in @reg
202 * @gate_flags: flags for gate-type clock
203 */
204 struct samsung_gate_clock {
205 unsigned int id;
206 const char *name;
207 const char *parent_name;
208 unsigned long flags;
209 unsigned long offset;
210 u8 bit_idx;
211 u8 gate_flags;
212 };
213
214 #define __GATE(_id, cname, pname, o, b, f, gf) \
215 { \
216 .id = _id, \
217 .name = cname, \
218 .parent_name = pname, \
219 .flags = f, \
220 .offset = o, \
221 .bit_idx = b, \
222 .gate_flags = gf, \
223 }
224
225 #define GATE(_id, cname, pname, o, b, f, gf) \
226 __GATE(_id, cname, pname, o, b, f, gf)
227
228 #define PNAME(x) static const char * const x[] __initconst
229
230 /**
231 * struct samsung_clk_reg_dump - register dump of clock controller registers
232 * @offset: clock register offset from the controller base address
233 * @value: the value to be register at offset
234 */
235 struct samsung_clk_reg_dump {
236 u32 offset;
237 u32 value;
238 };
239
240 /**
241 * struct samsung_pll_clock - information about pll clock
242 * @id: platform specific id of the clock
243 * @name: name of this pll clock
244 * @parent_name: name of the parent clock
245 * @flags: optional flags for basic clock
246 * @con_offset: offset of the register for configuring the PLL
247 * @lock_offset: offset of the register for locking the PLL
248 * @type: type of PLL to be registered
249 * @rate_table: array of PLL settings for possible PLL rates
250 */
251 struct samsung_pll_clock {
252 unsigned int id;
253 const char *name;
254 const char *parent_name;
255 unsigned long flags;
256 int con_offset;
257 int lock_offset;
258 enum samsung_pll_type type;
259 const struct samsung_pll_rate_table *rate_table;
260 };
261
262 #define __PLL(_typ, _id, _name, _pname, _flags, _lock, _con, _rtable) \
263 { \
264 .id = _id, \
265 .type = _typ, \
266 .name = _name, \
267 .parent_name = _pname, \
268 .flags = _flags, \
269 .con_offset = _con, \
270 .lock_offset = _lock, \
271 .rate_table = _rtable, \
272 }
273
274 #define PLL(_typ, _id, _name, _pname, _lock, _con, _rtable) \
275 __PLL(_typ, _id, _name, _pname, CLK_GET_RATE_NOCACHE, _lock, \
276 _con, _rtable)
277
278 struct samsung_cpu_clock {
279 unsigned int id;
280 const char *name;
281 unsigned int parent_id;
282 unsigned int alt_parent_id;
283 unsigned long flags;
284 int offset;
285 const struct exynos_cpuclk_cfg_data *cfg;
286 };
287
288 #define CPU_CLK(_id, _name, _pid, _apid, _flags, _offset, _cfg) \
289 { \
290 .id = _id, \
291 .name = _name, \
292 .parent_id = _pid, \
293 .alt_parent_id = _apid, \
294 .flags = _flags, \
295 .offset = _offset, \
296 .cfg = _cfg, \
297 }
298
299 struct samsung_clock_reg_cache {
300 struct list_head node;
301 void __iomem *reg_base;
302 struct samsung_clk_reg_dump *rdump;
303 unsigned int rd_num;
304 const struct samsung_clk_reg_dump *rsuspend;
305 unsigned int rsuspend_num;
306 };
307
308 /**
309 * struct samsung_cmu_info - all clocks information needed for CMU registration
310 * @pll_clks: list of PLL clocks
311 * @nr_pll_clks: count of clocks in @pll_clks
312 * @mux_clks: list of mux clocks
313 * @nr_mux_clks: count of clocks in @mux_clks
314 * @div_clks: list of div clocks
315 * @nr_div_clks: count of clocks in @div_clks
316 * @gate_clks: list of gate clocks
317 * @nr_gate_clks: count of clocks in @gate_clks
318 * @fixed_clks: list of fixed clocks
319 * @nr_fixed_clks: count clocks in @fixed_clks
320 * @fixed_factor_clks: list of fixed factor clocks
321 * @nr_fixed_factor_clks: count of clocks in @fixed_factor_clks
322 * @nr_clk_ids: total number of clocks with IDs assigned
323 * @cpu_clks: list of CPU clocks
324 * @nr_cpu_clks: count of clocks in @cpu_clks
325 * @clk_regs: list of clock registers
326 * @nr_clk_regs: count of clock registers in @clk_regs
327 * @suspend_regs: list of clock registers to set before suspend
328 * @nr_suspend_regs: count of clock registers in @suspend_regs
329 * @clk_name: name of the parent clock needed for CMU register access
330 */
331 struct samsung_cmu_info {
332 const struct samsung_pll_clock *pll_clks;
333 unsigned int nr_pll_clks;
334 const struct samsung_mux_clock *mux_clks;
335 unsigned int nr_mux_clks;
336 const struct samsung_div_clock *div_clks;
337 unsigned int nr_div_clks;
338 const struct samsung_gate_clock *gate_clks;
339 unsigned int nr_gate_clks;
340 const struct samsung_fixed_rate_clock *fixed_clks;
341 unsigned int nr_fixed_clks;
342 const struct samsung_fixed_factor_clock *fixed_factor_clks;
343 unsigned int nr_fixed_factor_clks;
344 unsigned int nr_clk_ids;
345 const struct samsung_cpu_clock *cpu_clks;
346 unsigned int nr_cpu_clks;
347
348 const unsigned long *clk_regs;
349 unsigned int nr_clk_regs;
350
351 const struct samsung_clk_reg_dump *suspend_regs;
352 unsigned int nr_suspend_regs;
353 const char *clk_name;
354 };
355
356 struct samsung_clk_provider *samsung_clk_init(struct device *dev,
357 void __iomem *base, unsigned long nr_clks);
358 void samsung_clk_of_add_provider(struct device_node *np,
359 struct samsung_clk_provider *ctx);
360 void samsung_clk_of_register_fixed_ext(
361 struct samsung_clk_provider *ctx,
362 struct samsung_fixed_rate_clock *fixed_rate_clk,
363 unsigned int nr_fixed_rate_clk,
364 const struct of_device_id *clk_matches);
365
366 void samsung_clk_add_lookup(struct samsung_clk_provider *ctx,
367 struct clk_hw *clk_hw, unsigned int id);
368
369 void samsung_clk_register_alias(struct samsung_clk_provider *ctx,
370 const struct samsung_clock_alias *list,
371 unsigned int nr_clk);
372 void samsung_clk_register_fixed_rate(
373 struct samsung_clk_provider *ctx,
374 const struct samsung_fixed_rate_clock *clk_list,
375 unsigned int nr_clk);
376 void samsung_clk_register_fixed_factor(
377 struct samsung_clk_provider *ctx,
378 const struct samsung_fixed_factor_clock *list,
379 unsigned int nr_clk);
380 void samsung_clk_register_mux(struct samsung_clk_provider *ctx,
381 const struct samsung_mux_clock *clk_list,
382 unsigned int nr_clk);
383 void samsung_clk_register_div(struct samsung_clk_provider *ctx,
384 const struct samsung_div_clock *clk_list,
385 unsigned int nr_clk);
386 void samsung_clk_register_gate(struct samsung_clk_provider *ctx,
387 const struct samsung_gate_clock *clk_list,
388 unsigned int nr_clk);
389 void samsung_clk_register_pll(struct samsung_clk_provider *ctx,
390 const struct samsung_pll_clock *pll_list,
391 unsigned int nr_clk);
392 void samsung_clk_register_cpu(struct samsung_clk_provider *ctx,
393 const struct samsung_cpu_clock *list, unsigned int nr_clk);
394
395 void samsung_cmu_register_clocks(struct samsung_clk_provider *ctx,
396 const struct samsung_cmu_info *cmu);
397 struct samsung_clk_provider *samsung_cmu_register_one(
398 struct device_node *,
399 const struct samsung_cmu_info *);
400
401 #ifdef CONFIG_PM_SLEEP
402 void samsung_clk_extended_sleep_init(void __iomem *reg_base,
403 const unsigned long *rdump,
404 unsigned long nr_rdump,
405 const struct samsung_clk_reg_dump *rsuspend,
406 unsigned long nr_rsuspend);
407 #else
samsung_clk_extended_sleep_init(void __iomem * reg_base,const unsigned long * rdump,unsigned long nr_rdump,const struct samsung_clk_reg_dump * rsuspend,unsigned long nr_rsuspend)408 static inline void samsung_clk_extended_sleep_init(void __iomem *reg_base,
409 const unsigned long *rdump,
410 unsigned long nr_rdump,
411 const struct samsung_clk_reg_dump *rsuspend,
412 unsigned long nr_rsuspend) {}
413 #endif
414 #define samsung_clk_sleep_init(reg_base, rdump, nr_rdump) \
415 samsung_clk_extended_sleep_init(reg_base, rdump, nr_rdump, NULL, 0)
416
417 void samsung_clk_save(void __iomem *base,
418 struct samsung_clk_reg_dump *rd,
419 unsigned int num_regs);
420 void samsung_clk_restore(void __iomem *base,
421 const struct samsung_clk_reg_dump *rd,
422 unsigned int num_regs);
423 struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump(
424 const unsigned long *rdump,
425 unsigned long nr_rdump);
426
427 #endif /* __SAMSUNG_CLK_H */
428