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