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