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 */
23struct 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 */
37struct 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 */
60struct 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 */
86struct 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 */
117struct 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 * @id: platform specific id of the clock.
150 * struct samsung_div_clock: information about div 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 * @div_flags: flags for div-type clock.
157 */
158struct samsung_div_clock {
159 unsigned int id;
160 const char *name;
161 const char *parent_name;
162 unsigned long flags;
163 unsigned long offset;
164 u8 shift;
165 u8 width;
166 u8 div_flags;
167 struct clk_div_table *table;
168};
169
170#define __DIV(_id, cname, pname, o, s, w, f, df, t) \
171 { \
172 .id = _id, \
173 .name = cname, \
174 .parent_name = pname, \
175 .flags = f, \
176 .offset = o, \
177 .shift = s, \
178 .width = w, \
179 .div_flags = df, \
180 .table = t, \
181 }
182
183#define DIV(_id, cname, pname, o, s, w) \
184 __DIV(_id, cname, pname, o, s, w, 0, 0, NULL)
185
186#define DIV_F(_id, cname, pname, o, s, w, f, df) \
187 __DIV(_id, cname, pname, o, s, w, f, df, NULL)
188
189#define DIV_T(_id, cname, pname, o, s, w, t) \
190 __DIV(_id, cname, pname, o, s, w, 0, 0, t)
191
192/**
193 * struct samsung_gate_clock: information about gate clock
194 * @id: platform specific id of the clock.
195 * @name: name of this gate clock.
196 * @parent_name: name of the parent clock.
197 * @flags: optional flags for basic clock.
198 * @offset: offset of the register for configuring the gate.
199 * @bit_idx: bit index of the gate control bit-field in @reg.
200 * @gate_flags: flags for gate-type clock.
201 */
202struct samsung_gate_clock {
203 unsigned int id;
204 const char *name;
205 const char *parent_name;
206 unsigned long flags;
207 unsigned long offset;
208 u8 bit_idx;
209 u8 gate_flags;
210};
211
212#define __GATE(_id, cname, pname, o, b, f, gf) \
213 { \
214 .id = _id, \
215 .name = cname, \
216 .parent_name = pname, \
217 .flags = f, \
218 .offset = o, \
219 .bit_idx = b, \
220 .gate_flags = gf, \
221 }
222
223#define GATE(_id, cname, pname, o, b, f, gf) \
224 __GATE(_id, cname, pname, o, b, f, gf)
225
226#define PNAME(x) static const char * const x[] __initconst
227
228/**
229 * struct samsung_clk_reg_dump: register dump of clock controller registers.
230 * @offset: clock register offset from the controller base address.
231 * @value: the value to be register at offset.
232 */
233struct samsung_clk_reg_dump {
234 u32 offset;
235 u32 value;
236};
237
238/**
239 * struct samsung_pll_clock: information about pll clock
240 * @id: platform specific id of the clock.
241 * @name: name of this pll clock.
242 * @parent_name: name of the parent clock.
243 * @flags: optional flags for basic clock.
244 * @con_offset: offset of the register for configuring the PLL.
245 * @lock_offset: offset of the register for locking the PLL.
246 * @type: Type of PLL to be registered.
247 */
248struct samsung_pll_clock {
249 unsigned int id;
250 const char *name;
251 const char *parent_name;
252 unsigned long flags;
253 int con_offset;
254 int lock_offset;
255 enum samsung_pll_type type;
256 const struct samsung_pll_rate_table *rate_table;
257};
258
259#define __PLL(_typ, _id, _name, _pname, _flags, _lock, _con, _rtable) \
260 { \
261 .id = _id, \
262 .type = _typ, \
263 .name = _name, \
264 .parent_name = _pname, \
265 .flags = _flags, \
266 .con_offset = _con, \
267 .lock_offset = _lock, \
268 .rate_table = _rtable, \
269 }
270
271#define PLL(_typ, _id, _name, _pname, _lock, _con, _rtable) \
272 __PLL(_typ, _id, _name, _pname, CLK_GET_RATE_NOCACHE, _lock, \
273 _con, _rtable)
274
275struct samsung_cpu_clock {
276 unsigned int id;
277 const char *name;
278 unsigned int parent_id;
279 unsigned int alt_parent_id;
280 unsigned long flags;
281 int offset;
282 const struct exynos_cpuclk_cfg_data *cfg;
283};
284
285#define CPU_CLK(_id, _name, _pid, _apid, _flags, _offset, _cfg) \
286 { \
287 .id = _id, \
288 .name = _name, \
289 .parent_id = _pid, \
290 .alt_parent_id = _apid, \
291 .flags = _flags, \
292 .offset = _offset, \
293 .cfg = _cfg, \
294 }
295
296struct samsung_clock_reg_cache {
297 struct list_head node;
298 void __iomem *reg_base;
299 struct samsung_clk_reg_dump *rdump;
300 unsigned int rd_num;
301 const struct samsung_clk_reg_dump *rsuspend;
302 unsigned int rsuspend_num;
303};
304
305struct samsung_cmu_info {
306 /* list of pll clocks and respective count */
307 const struct samsung_pll_clock *pll_clks;
308 unsigned int nr_pll_clks;
309 /* list of mux clocks and respective count */
310 const struct samsung_mux_clock *mux_clks;
311 unsigned int nr_mux_clks;
312 /* list of div clocks and respective count */
313 const struct samsung_div_clock *div_clks;
314 unsigned int nr_div_clks;
315 /* list of gate clocks and respective count */
316 const struct samsung_gate_clock *gate_clks;
317 unsigned int nr_gate_clks;
318 /* list of fixed clocks and respective count */
319 const struct samsung_fixed_rate_clock *fixed_clks;
320 unsigned int nr_fixed_clks;
321 /* list of fixed factor clocks and respective count */
322 const struct samsung_fixed_factor_clock *fixed_factor_clks;
323 unsigned int nr_fixed_factor_clks;
324 /* total number of clocks with IDs assigned*/
325 unsigned int nr_clk_ids;
326 /* list of cpu clocks and respective count */
327 const struct samsung_cpu_clock *cpu_clks;
328 unsigned int nr_cpu_clks;
329
330 /* list and number of clocks registers */
331 const unsigned long *clk_regs;
332 unsigned int nr_clk_regs;
333
334 /* list and number of clocks registers to set before suspend */
335 const struct samsung_clk_reg_dump *suspend_regs;
336 unsigned int nr_suspend_regs;
337 /* name of the parent clock needed for CMU register access */
338 const char *clk_name;
339};
340
341struct samsung_clk_provider *samsung_clk_init(struct device *dev,
342 void __iomem *base, unsigned long nr_clks);
343void samsung_clk_of_add_provider(struct device_node *np,
344 struct samsung_clk_provider *ctx);
345void samsung_clk_of_register_fixed_ext(
346 struct samsung_clk_provider *ctx,
347 struct samsung_fixed_rate_clock *fixed_rate_clk,
348 unsigned int nr_fixed_rate_clk,
349 const struct of_device_id *clk_matches);
350
351void samsung_clk_add_lookup(struct samsung_clk_provider *ctx,
352 struct clk_hw *clk_hw, unsigned int id);
353
354void samsung_clk_register_alias(struct samsung_clk_provider *ctx,
355 const struct samsung_clock_alias *list,
356 unsigned int nr_clk);
357void samsung_clk_register_fixed_rate(
358 struct samsung_clk_provider *ctx,
359 const struct samsung_fixed_rate_clock *clk_list,
360 unsigned int nr_clk);
361void samsung_clk_register_fixed_factor(
362 struct samsung_clk_provider *ctx,
363 const struct samsung_fixed_factor_clock *list,
364 unsigned int nr_clk);
365void samsung_clk_register_mux(struct samsung_clk_provider *ctx,
366 const struct samsung_mux_clock *clk_list,
367 unsigned int nr_clk);
368void samsung_clk_register_div(struct samsung_clk_provider *ctx,
369 const struct samsung_div_clock *clk_list,
370 unsigned int nr_clk);
371void samsung_clk_register_gate(struct samsung_clk_provider *ctx,
372 const struct samsung_gate_clock *clk_list,
373 unsigned int nr_clk);
374void samsung_clk_register_pll(struct samsung_clk_provider *ctx,
375 const struct samsung_pll_clock *pll_list,
376 unsigned int nr_clk);
377void samsung_clk_register_cpu(struct samsung_clk_provider *ctx,
378 const struct samsung_cpu_clock *list, unsigned int nr_clk);
379
380void samsung_cmu_register_clocks(struct samsung_clk_provider *ctx,
381 const struct samsung_cmu_info *cmu);
382struct samsung_clk_provider *samsung_cmu_register_one(
383 struct device_node *,
384 const struct samsung_cmu_info *);
385
386#ifdef CONFIG_PM_SLEEP
387void samsung_clk_extended_sleep_init(void __iomem *reg_base,
388 const unsigned long *rdump,
389 unsigned long nr_rdump,
390 const struct samsung_clk_reg_dump *rsuspend,
391 unsigned long nr_rsuspend);
392#else
393static inline void samsung_clk_extended_sleep_init(void __iomem *reg_base,
394 const unsigned long *rdump,
395 unsigned long nr_rdump,
396 const struct samsung_clk_reg_dump *rsuspend,
397 unsigned long nr_rsuspend) {}
398#endif
399#define samsung_clk_sleep_init(reg_base, rdump, nr_rdump) \
400 samsung_clk_extended_sleep_init(reg_base, rdump, nr_rdump, NULL, 0)
401
402void samsung_clk_save(void __iomem *base,
403 struct samsung_clk_reg_dump *rd,
404 unsigned int num_regs);
405void samsung_clk_restore(void __iomem *base,
406 const struct samsung_clk_reg_dump *rd,
407 unsigned int num_regs);
408struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump(
409 const unsigned long *rdump,
410 unsigned long nr_rdump);
411
412#endif /* __SAMSUNG_CLK_H */
413

source code of linux/drivers/clk/samsung/clk.h