[go: nahoru, domu]

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 */
30struct 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 */
42struct 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 */
65struct 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 */
91struct 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 */
124struct 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 */
177struct 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 */
230struct 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 */
274struct 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 */
291struct 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
327extern struct samsung_clk_provider *__init samsung_clk_init(
328			struct device_node *np, void __iomem *base,
329			unsigned long nr_clks);
330extern void __init samsung_clk_of_add_provider(struct device_node *np,
331			struct samsung_clk_provider *ctx);
332extern 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
338extern void samsung_clk_add_lookup(struct samsung_clk_provider *ctx,
339			struct clk *clk, unsigned int id);
340
341extern void samsung_clk_register_alias(struct samsung_clk_provider *ctx,
342			struct samsung_clock_alias *list,
343			unsigned int nr_clk);
344extern 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);
348extern 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);
352extern void __init samsung_clk_register_mux(struct samsung_clk_provider *ctx,
353			struct samsung_mux_clock *clk_list,
354			unsigned int nr_clk);
355extern void __init samsung_clk_register_div(struct samsung_clk_provider *ctx,
356			struct samsung_div_clock *clk_list,
357			unsigned int nr_clk);
358extern void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx,
359			struct samsung_gate_clock *clk_list,
360			unsigned int nr_clk);
361extern 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
365extern unsigned long _get_rate(const char *clk_name);
366
367extern void samsung_clk_save(void __iomem *base,
368			struct samsung_clk_reg_dump *rd,
369			unsigned int num_regs);
370extern void samsung_clk_restore(void __iomem *base,
371			const struct samsung_clk_reg_dump *rd,
372			unsigned int num_regs);
373extern 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