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