• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  * @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  */
158 struct 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  */
202 struct 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  */
233 struct 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  */
248 struct 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 
275 struct 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 
296 struct 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 
305 struct 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 
341 struct samsung_clk_provider *samsung_clk_init(struct device *dev,
342 			void __iomem *base, unsigned long nr_clks);
343 void samsung_clk_of_add_provider(struct device_node *np,
344 			struct samsung_clk_provider *ctx);
345 void 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 
351 void samsung_clk_add_lookup(struct samsung_clk_provider *ctx,
352 			struct clk_hw *clk_hw, unsigned int id);
353 
354 void samsung_clk_register_alias(struct samsung_clk_provider *ctx,
355 			const struct samsung_clock_alias *list,
356 			unsigned int nr_clk);
357 void 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);
361 void samsung_clk_register_fixed_factor(
362 			struct samsung_clk_provider *ctx,
363 			const struct samsung_fixed_factor_clock *list,
364 			unsigned int nr_clk);
365 void samsung_clk_register_mux(struct samsung_clk_provider *ctx,
366 			const struct samsung_mux_clock *clk_list,
367 			unsigned int nr_clk);
368 void samsung_clk_register_div(struct samsung_clk_provider *ctx,
369 			const struct samsung_div_clock *clk_list,
370 			unsigned int nr_clk);
371 void samsung_clk_register_gate(struct samsung_clk_provider *ctx,
372 			const struct samsung_gate_clock *clk_list,
373 			unsigned int nr_clk);
374 void samsung_clk_register_pll(struct samsung_clk_provider *ctx,
375 			const struct samsung_pll_clock *pll_list,
376 			unsigned int nr_clk);
377 void samsung_clk_register_cpu(struct samsung_clk_provider *ctx,
378 		const struct samsung_cpu_clock *list, unsigned int nr_clk);
379 
380 void samsung_cmu_register_clocks(struct samsung_clk_provider *ctx,
381 				 const struct samsung_cmu_info *cmu);
382 struct samsung_clk_provider *samsung_cmu_register_one(
383 			struct device_node *,
384 			const struct samsung_cmu_info *);
385 
386 #ifdef CONFIG_PM_SLEEP
387 void 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
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)393 static 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 
402 void samsung_clk_save(void __iomem *base,
403 			struct samsung_clk_reg_dump *rd,
404 			unsigned int num_regs);
405 void samsung_clk_restore(void __iomem *base,
406 			const struct samsung_clk_reg_dump *rd,
407 			unsigned int num_regs);
408 struct 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