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 */
24struct 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 */
38struct 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 */
61struct 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 */
87struct 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 */
118struct 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 */
161struct 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 */
205struct 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 */
236struct 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 */
252struct 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
279struct 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
302struct 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 */
334struct 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
359struct samsung_clk_provider *samsung_clk_init(struct device *dev,
360			void __iomem *base, unsigned long nr_clks);
361void samsung_clk_of_add_provider(struct device_node *np,
362			struct samsung_clk_provider *ctx);
363void 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
369void samsung_clk_add_lookup(struct samsung_clk_provider *ctx,
370			struct clk_hw *clk_hw, unsigned int id);
371
372void samsung_clk_register_alias(struct samsung_clk_provider *ctx,
373			const struct samsung_clock_alias *list,
374			unsigned int nr_clk);
375void 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);
379void samsung_clk_register_fixed_factor(
380			struct samsung_clk_provider *ctx,
381			const struct samsung_fixed_factor_clock *list,
382			unsigned int nr_clk);
383void samsung_clk_register_mux(struct samsung_clk_provider *ctx,
384			const struct samsung_mux_clock *clk_list,
385			unsigned int nr_clk);
386void samsung_clk_register_div(struct samsung_clk_provider *ctx,
387			const struct samsung_div_clock *clk_list,
388			unsigned int nr_clk);
389void samsung_clk_register_gate(struct samsung_clk_provider *ctx,
390			const struct samsung_gate_clock *clk_list,
391			unsigned int nr_clk);
392void samsung_clk_register_pll(struct samsung_clk_provider *ctx,
393			const struct samsung_pll_clock *pll_list,
394			unsigned int nr_clk);
395void samsung_clk_register_cpu(struct samsung_clk_provider *ctx,
396		const struct samsung_cpu_clock *list, unsigned int nr_clk);
397
398void samsung_cmu_register_clocks(struct samsung_clk_provider *ctx,
399				 const struct samsung_cmu_info *cmu);
400struct samsung_clk_provider *samsung_cmu_register_one(
401			struct device_node *,
402			const struct samsung_cmu_info *);
403
404#ifdef CONFIG_PM_SLEEP
405void 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
411static 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
420void samsung_clk_save(void __iomem *base,
421			struct samsung_clk_reg_dump *rd,
422			unsigned int num_regs);
423void samsung_clk_restore(void __iomem *base,
424			const struct samsung_clk_reg_dump *rd,
425			unsigned int num_regs);
426struct 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