• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013 Samsung Electronics Co., Ltd.
3  * Copyright (c) 2013 Linaro Ltd.
4  * Author: Thomas Abraham <thomas.ab@samsung.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * Common Clock Framework support for all Samsung platforms
11 */
12 
13 #ifndef __SAMSUNG_CLK_H
14 #define __SAMSUNG_CLK_H
15 
16 #include <linux/clk.h>
17 #include <linux/clkdev.h>
18 #include <linux/io.h>
19 #include <linux/clk-provider.h>
20 #include <linux/of.h>
21 #include <linux/of_address.h>
22 #include "clk-pll.h"
23 
24 /**
25  * struct samsung_clk_provider: information about clock provider
26  * @reg_base: virtual address for the register base.
27  * @clk_data: holds clock related data like clk* and number of clocks.
28  * @lock: maintains exclusion bwtween callbacks for a given clock-provider.
29  */
30 struct samsung_clk_provider {
31 	void __iomem *reg_base;
32 	struct clk_onecell_data clk_data;
33 	spinlock_t lock;
34 };
35 
36 /**
37  * struct samsung_clock_alias: information about mux clock
38  * @id: platform specific id of the clock.
39  * @dev_name: name of the device to which this clock belongs.
40  * @alias: optional clock alias name to be assigned to this clock.
41  */
42 struct samsung_clock_alias {
43 	unsigned int		id;
44 	const char		*dev_name;
45 	const char		*alias;
46 };
47 
48 #define ALIAS(_id, dname, a)	\
49 	{							\
50 		.id		= _id,				\
51 		.dev_name	= dname,			\
52 		.alias		= a,				\
53 	}
54 
55 #define MHZ (1000 * 1000)
56 
57 /**
58  * struct samsung_fixed_rate_clock: information about fixed-rate clock
59  * @id: platform specific id of the clock.
60  * @name: name of this fixed-rate clock.
61  * @parent_name: optional parent clock name.
62  * @flags: optional fixed-rate clock flags.
63  * @fixed-rate: fixed clock rate of this clock.
64  */
65 struct samsung_fixed_rate_clock {
66 	unsigned int		id;
67 	char			*name;
68 	const char		*parent_name;
69 	unsigned long		flags;
70 	unsigned long		fixed_rate;
71 };
72 
73 #define FRATE(_id, cname, pname, f, frate)		\
74 	{						\
75 		.id		= _id,			\
76 		.name		= cname,		\
77 		.parent_name	= pname,		\
78 		.flags		= f,			\
79 		.fixed_rate	= frate,		\
80 	}
81 
82 /*
83  * struct samsung_fixed_factor_clock: information about fixed-factor clock
84  * @id: platform specific id of the clock.
85  * @name: name of this fixed-factor clock.
86  * @parent_name: parent clock name.
87  * @mult: fixed multiplication factor.
88  * @div: fixed division factor.
89  * @flags: optional fixed-factor clock flags.
90  */
91 struct samsung_fixed_factor_clock {
92 	unsigned int		id;
93 	char			*name;
94 	const char		*parent_name;
95 	unsigned long		mult;
96 	unsigned long		div;
97 	unsigned long		flags;
98 };
99 
100 #define FFACTOR(_id, cname, pname, m, d, f)		\
101 	{						\
102 		.id		= _id,			\
103 		.name		= cname,		\
104 		.parent_name	= pname,		\
105 		.mult		= m,			\
106 		.div		= d,			\
107 		.flags		= f,			\
108 	}
109 
110 /**
111  * struct samsung_mux_clock: information about mux clock
112  * @id: platform specific id of the clock.
113  * @dev_name: name of the device to which this clock belongs.
114  * @name: name of this mux clock.
115  * @parent_names: array of pointer to parent clock names.
116  * @num_parents: number of parents listed in @parent_names.
117  * @flags: optional flags for basic clock.
118  * @offset: offset of the register for configuring the mux.
119  * @shift: starting bit location of the mux control bit-field in @reg.
120  * @width: width of the mux control bit-field in @reg.
121  * @mux_flags: flags for mux-type clock.
122  * @alias: optional clock alias name to be assigned to this clock.
123  */
124 struct samsung_mux_clock {
125 	unsigned int		id;
126 	const char		*dev_name;
127 	const char		*name;
128 	const char		**parent_names;
129 	u8			num_parents;
130 	unsigned long		flags;
131 	unsigned long		offset;
132 	u8			shift;
133 	u8			width;
134 	u8			mux_flags;
135 	const char		*alias;
136 };
137 
138 #define __MUX(_id, dname, cname, pnames, o, s, w, f, mf, a)	\
139 	{							\
140 		.id		= _id,				\
141 		.dev_name	= dname,			\
142 		.name		= cname,			\
143 		.parent_names	= pnames,			\
144 		.num_parents	= ARRAY_SIZE(pnames),		\
145 		.flags		= (f) | CLK_SET_RATE_NO_REPARENT, \
146 		.offset		= o,				\
147 		.shift		= s,				\
148 		.width		= w,				\
149 		.mux_flags	= mf,				\
150 		.alias		= a,				\
151 	}
152 
153 #define MUX(_id, cname, pnames, o, s, w)			\
154 	__MUX(_id, NULL, cname, pnames, o, s, w, 0, 0, NULL)
155 
156 #define MUX_A(_id, cname, pnames, o, s, w, a)			\
157 	__MUX(_id, NULL, cname, pnames, o, s, w, 0, 0, a)
158 
159 #define MUX_F(_id, cname, pnames, o, s, w, f, mf)		\
160 	__MUX(_id, NULL, cname, pnames, o, s, w, f, mf, NULL)
161 
162 #define MUX_FA(_id, cname, pnames, o, s, w, f, mf, a)		\
163 	__MUX(_id, NULL, cname, pnames, o, s, w, f, mf, a)
164 
165 /**
166  * @id: platform specific id of the clock.
167  * struct samsung_div_clock: information about div clock
168  * @dev_name: name of the device to which this clock belongs.
169  * @name: name of this div clock.
170  * @parent_name: name of the parent clock.
171  * @flags: optional flags for basic clock.
172  * @offset: offset of the register for configuring the div.
173  * @shift: starting bit location of the div control bit-field in @reg.
174  * @div_flags: flags for div-type clock.
175  * @alias: optional clock alias name to be assigned to this clock.
176  */
177 struct samsung_div_clock {
178 	unsigned int		id;
179 	const char		*dev_name;
180 	const char		*name;
181 	const char		*parent_name;
182 	unsigned long		flags;
183 	unsigned long		offset;
184 	u8			shift;
185 	u8			width;
186 	u8			div_flags;
187 	const char		*alias;
188 	struct clk_div_table	*table;
189 };
190 
191 #define __DIV(_id, dname, cname, pname, o, s, w, f, df, a, t)	\
192 	{							\
193 		.id		= _id,				\
194 		.dev_name	= dname,			\
195 		.name		= cname,			\
196 		.parent_name	= pname,			\
197 		.flags		= f,				\
198 		.offset		= o,				\
199 		.shift		= s,				\
200 		.width		= w,				\
201 		.div_flags	= df,				\
202 		.alias		= a,				\
203 		.table		= t,				\
204 	}
205 
206 #define DIV(_id, cname, pname, o, s, w)				\
207 	__DIV(_id, NULL, cname, pname, o, s, w, 0, 0, NULL, NULL)
208 
209 #define DIV_A(_id, cname, pname, o, s, w, a)			\
210 	__DIV(_id, NULL, cname, pname, o, s, w, 0, 0, a, NULL)
211 
212 #define DIV_F(_id, cname, pname, o, s, w, f, df)		\
213 	__DIV(_id, NULL, cname, pname, o, s, w, f, df, NULL, NULL)
214 
215 #define DIV_T(_id, cname, pname, o, s, w, t)			\
216 	__DIV(_id, NULL, cname, pname, o, s, w, 0, 0, NULL, t)
217 
218 /**
219  * struct samsung_gate_clock: information about gate clock
220  * @id: platform specific id of the clock.
221  * @dev_name: name of the device to which this clock belongs.
222  * @name: name of this gate clock.
223  * @parent_name: name of the parent clock.
224  * @flags: optional flags for basic clock.
225  * @offset: offset of the register for configuring the gate.
226  * @bit_idx: bit index of the gate control bit-field in @reg.
227  * @gate_flags: flags for gate-type clock.
228  * @alias: optional clock alias name to be assigned to this clock.
229  */
230 struct samsung_gate_clock {
231 	unsigned int		id;
232 	const char		*dev_name;
233 	const char		*name;
234 	const char		*parent_name;
235 	unsigned long		flags;
236 	unsigned long		offset;
237 	u8			bit_idx;
238 	u8			gate_flags;
239 	const char		*alias;
240 };
241 
242 #define __GATE(_id, dname, cname, pname, o, b, f, gf, a)	\
243 	{							\
244 		.id		= _id,				\
245 		.dev_name	= dname,			\
246 		.name		= cname,			\
247 		.parent_name	= pname,			\
248 		.flags		= f,				\
249 		.offset		= o,				\
250 		.bit_idx	= b,				\
251 		.gate_flags	= gf,				\
252 		.alias		= a,				\
253 	}
254 
255 #define GATE(_id, cname, pname, o, b, f, gf)			\
256 	__GATE(_id, NULL, cname, pname, o, b, f, gf, NULL)
257 
258 #define GATE_A(_id, cname, pname, o, b, f, gf, a)		\
259 	__GATE(_id, NULL, cname, pname, o, b, f, gf, a)
260 
261 #define GATE_D(_id, dname, cname, pname, o, b, f, gf)		\
262 	__GATE(_id, dname, cname, pname, o, b, f, gf, NULL)
263 
264 #define GATE_DA(_id, dname, cname, pname, o, b, f, gf, a)	\
265 	__GATE(_id, dname, cname, pname, o, b, f, gf, a)
266 
267 #define PNAME(x) static const char *x[] __initdata
268 
269 /**
270  * struct samsung_clk_reg_dump: register dump of clock controller registers.
271  * @offset: clock register offset from the controller base address.
272  * @value: the value to be register at offset.
273  */
274 struct samsung_clk_reg_dump {
275 	u32	offset;
276 	u32	value;
277 };
278 
279 /**
280  * struct samsung_pll_clock: information about pll clock
281  * @id: platform specific id of the clock.
282  * @dev_name: name of the device to which this clock belongs.
283  * @name: name of this pll clock.
284  * @parent_name: name of the parent clock.
285  * @flags: optional flags for basic clock.
286  * @con_offset: offset of the register for configuring the PLL.
287  * @lock_offset: offset of the register for locking the PLL.
288  * @type: Type of PLL to be registered.
289  * @alias: optional clock alias name to be assigned to this clock.
290  */
291 struct samsung_pll_clock {
292 	unsigned int		id;
293 	const char		*dev_name;
294 	const char		*name;
295 	const char		*parent_name;
296 	unsigned long		flags;
297 	int			con_offset;
298 	int			lock_offset;
299 	enum samsung_pll_type	type;
300 	const struct samsung_pll_rate_table *rate_table;
301 	const char              *alias;
302 };
303 
304 #define __PLL(_typ, _id, _dname, _name, _pname, _flags, _lock, _con,	\
305 		_rtable, _alias)					\
306 	{								\
307 		.id		= _id,					\
308 		.type		= _typ,					\
309 		.dev_name	= _dname,				\
310 		.name		= _name,				\
311 		.parent_name	= _pname,				\
312 		.flags		= CLK_GET_RATE_NOCACHE,			\
313 		.con_offset	= _con,					\
314 		.lock_offset	= _lock,				\
315 		.rate_table	= _rtable,				\
316 		.alias		= _alias,				\
317 	}
318 
319 #define PLL(_typ, _id, _name, _pname, _lock, _con, _rtable)	\
320 	__PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE,	\
321 		_lock, _con, _rtable, _name)
322 
323 #define PLL_A(_typ, _id, _name, _pname, _lock, _con, _alias, _rtable) \
324 	__PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE,	\
325 		_lock, _con, _rtable, _alias)
326 
327 extern struct samsung_clk_provider *__init samsung_clk_init(
328 			struct device_node *np, void __iomem *base,
329 			unsigned long nr_clks);
330 extern void __init samsung_clk_of_add_provider(struct device_node *np,
331 			struct samsung_clk_provider *ctx);
332 extern void __init samsung_clk_of_register_fixed_ext(
333 			struct samsung_clk_provider *ctx,
334 			struct samsung_fixed_rate_clock *fixed_rate_clk,
335 			unsigned int nr_fixed_rate_clk,
336 			const struct of_device_id *clk_matches);
337 
338 extern void samsung_clk_add_lookup(struct samsung_clk_provider *ctx,
339 			struct clk *clk, unsigned int id);
340 
341 extern void samsung_clk_register_alias(struct samsung_clk_provider *ctx,
342 			struct samsung_clock_alias *list,
343 			unsigned int nr_clk);
344 extern void __init samsung_clk_register_fixed_rate(
345 			struct samsung_clk_provider *ctx,
346 			struct samsung_fixed_rate_clock *clk_list,
347 			unsigned int nr_clk);
348 extern void __init samsung_clk_register_fixed_factor(
349 			struct samsung_clk_provider *ctx,
350 			struct samsung_fixed_factor_clock *list,
351 			unsigned int nr_clk);
352 extern void __init samsung_clk_register_mux(struct samsung_clk_provider *ctx,
353 			struct samsung_mux_clock *clk_list,
354 			unsigned int nr_clk);
355 extern void __init samsung_clk_register_div(struct samsung_clk_provider *ctx,
356 			struct samsung_div_clock *clk_list,
357 			unsigned int nr_clk);
358 extern void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx,
359 			struct samsung_gate_clock *clk_list,
360 			unsigned int nr_clk);
361 extern void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx,
362 			struct samsung_pll_clock *pll_list,
363 			unsigned int nr_clk, void __iomem *base);
364 
365 extern unsigned long _get_rate(const char *clk_name);
366 
367 extern void samsung_clk_save(void __iomem *base,
368 			struct samsung_clk_reg_dump *rd,
369 			unsigned int num_regs);
370 extern void samsung_clk_restore(void __iomem *base,
371 			const struct samsung_clk_reg_dump *rd,
372 			unsigned int num_regs);
373 extern struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump(
374 			const unsigned long *rdump,
375 			unsigned long nr_rdump);
376 
377 #endif /* __SAMSUNG_CLK_H */
378