File Index
Files and directories
Sign in
FILE

clk.h

File preview with syntax highlighting.

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