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   */
24  struct 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   */
38  struct 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   */
61  struct 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   */
87  struct 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   */
118  struct 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,				\
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, CLK_SET_RATE_NO_REPARENT, 0)
145  
146  #define MUX_F(_id, cname, pnames, o, s, w, f, mf)		\
147  	__MUX(_id, cname, pnames, o, s, w, (f) | CLK_SET_RATE_NO_REPARENT, mf)
148  
149  /* Used by MUX clocks where reparenting on clock rate change is allowed. */
150  #define nMUX(_id, cname, pnames, o, s, w)			\
151  	__MUX(_id, cname, pnames, o, s, w, 0, 0)
152  
153  #define nMUX_F(_id, cname, pnames, o, s, w, f, mf)		\
154  	__MUX(_id, cname, pnames, o, s, w, f, mf)
155  
156  /**
157   * struct samsung_div_clock - information about div clock
158   * @id: platform specific id of the clock
159   * @name: name of this div clock
160   * @parent_name: name of the parent clock
161   * @flags: optional flags for basic clock
162   * @offset: offset of the register for configuring the div
163   * @shift: starting bit location of the div control bit-field in @reg
164   * @width: width of the bitfield
165   * @div_flags: flags for div-type clock
166   * @table: array of divider/value pairs ending with a div set to 0
167   */
168  struct samsung_div_clock {
169  	unsigned int		id;
170  	const char		*name;
171  	const char		*parent_name;
172  	unsigned long		flags;
173  	unsigned long		offset;
174  	u8			shift;
175  	u8			width;
176  	u8			div_flags;
177  	struct clk_div_table	*table;
178  };
179  
180  #define __DIV(_id, cname, pname, o, s, w, f, df, t)	\
181  	{							\
182  		.id		= _id,				\
183  		.name		= cname,			\
184  		.parent_name	= pname,			\
185  		.flags		= f,				\
186  		.offset		= o,				\
187  		.shift		= s,				\
188  		.width		= w,				\
189  		.div_flags	= df,				\
190  		.table		= t,				\
191  	}
192  
193  #define DIV(_id, cname, pname, o, s, w)				\
194  	__DIV(_id, cname, pname, o, s, w, 0, 0, NULL)
195  
196  #define DIV_F(_id, cname, pname, o, s, w, f, df)		\
197  	__DIV(_id, cname, pname, o, s, w, f, df, NULL)
198  
199  #define DIV_T(_id, cname, pname, o, s, w, t)			\
200  	__DIV(_id, cname, pname, o, s, w, 0, 0, t)
201  
202  /**
203   * struct samsung_gate_clock - information about gate clock
204   * @id: platform specific id of the clock
205   * @name: name of this gate clock
206   * @parent_name: name of the parent clock
207   * @flags: optional flags for basic clock
208   * @offset: offset of the register for configuring the gate
209   * @bit_idx: bit index of the gate control bit-field in @reg
210   * @gate_flags: flags for gate-type clock
211   */
212  struct samsung_gate_clock {
213  	unsigned int		id;
214  	const char		*name;
215  	const char		*parent_name;
216  	unsigned long		flags;
217  	unsigned long		offset;
218  	u8			bit_idx;
219  	u8			gate_flags;
220  };
221  
222  #define __GATE(_id, cname, pname, o, b, f, gf)			\
223  	{							\
224  		.id		= _id,				\
225  		.name		= cname,			\
226  		.parent_name	= pname,			\
227  		.flags		= f,				\
228  		.offset		= o,				\
229  		.bit_idx	= b,				\
230  		.gate_flags	= gf,				\
231  	}
232  
233  #define GATE(_id, cname, pname, o, b, f, gf)			\
234  	__GATE(_id, cname, pname, o, b, f, gf)
235  
236  #define PNAME(x) static const char * const x[] __initconst
237  
238  /**
239   * struct samsung_clk_reg_dump - register dump of clock controller registers
240   * @offset: clock register offset from the controller base address
241   * @value: the value to be register at offset
242   */
243  struct samsung_clk_reg_dump {
244  	u32	offset;
245  	u32	value;
246  };
247  
248  /**
249   * struct samsung_pll_clock - information about pll clock
250   * @id: platform specific id of the clock
251   * @name: name of this pll clock
252   * @parent_name: name of the parent clock
253   * @flags: optional flags for basic clock
254   * @con_offset: offset of the register for configuring the PLL
255   * @lock_offset: offset of the register for locking the PLL
256   * @type: type of PLL to be registered
257   * @rate_table: array of PLL settings for possible PLL rates
258   */
259  struct samsung_pll_clock {
260  	unsigned int		id;
261  	const char		*name;
262  	const char		*parent_name;
263  	unsigned long		flags;
264  	int			con_offset;
265  	int			lock_offset;
266  	enum samsung_pll_type	type;
267  	const struct samsung_pll_rate_table *rate_table;
268  };
269  
270  #define __PLL(_typ, _id, _name, _pname, _flags, _lock, _con, _rtable)	\
271  	{								\
272  		.id		= _id,					\
273  		.type		= _typ,					\
274  		.name		= _name,				\
275  		.parent_name	= _pname,				\
276  		.flags		= _flags,				\
277  		.con_offset	= _con,					\
278  		.lock_offset	= _lock,				\
279  		.rate_table	= _rtable,				\
280  	}
281  
282  #define PLL(_typ, _id, _name, _pname, _lock, _con, _rtable)	\
283  	__PLL(_typ, _id, _name, _pname, CLK_GET_RATE_NOCACHE, _lock,	\
284  	      _con, _rtable)
285  
286  struct samsung_cpu_clock {
287  	unsigned int	id;
288  	const char	*name;
289  	unsigned int	parent_id;
290  	unsigned int	alt_parent_id;
291  	unsigned long	flags;
292  	int		offset;
293  	enum exynos_cpuclk_layout reg_layout;
294  	const struct exynos_cpuclk_cfg_data *cfg;
295  };
296  
297  #define CPU_CLK(_id, _name, _pid, _apid, _flags, _offset, _layout, _cfg) \
298  	{							\
299  		.id		  = _id,			\
300  		.name		  = _name,			\
301  		.parent_id	  = _pid,			\
302  		.alt_parent_id	  = _apid,			\
303  		.flags		  = _flags,			\
304  		.offset		  = _offset,			\
305  		.reg_layout	  = _layout,			\
306  		.cfg		  = _cfg,			\
307  	}
308  
309  struct samsung_clock_reg_cache {
310  	struct list_head node;
311  	void __iomem *reg_base;
312  	struct samsung_clk_reg_dump *rdump;
313  	unsigned int rd_num;
314  	const struct samsung_clk_reg_dump *rsuspend;
315  	unsigned int rsuspend_num;
316  };
317  
318  /**
319   * struct samsung_cmu_info - all clocks information needed for CMU registration
320   * @pll_clks: list of PLL clocks
321   * @nr_pll_clks: count of clocks in @pll_clks
322   * @mux_clks: list of mux clocks
323   * @nr_mux_clks: count of clocks in @mux_clks
324   * @div_clks: list of div clocks
325   * @nr_div_clks: count of clocks in @div_clks
326   * @gate_clks: list of gate clocks
327   * @nr_gate_clks: count of clocks in @gate_clks
328   * @fixed_clks: list of fixed clocks
329   * @nr_fixed_clks: count clocks in @fixed_clks
330   * @fixed_factor_clks: list of fixed factor clocks
331   * @nr_fixed_factor_clks: count of clocks in @fixed_factor_clks
332   * @nr_clk_ids: total number of clocks with IDs assigned
333   * @cpu_clks: list of CPU clocks
334   * @nr_cpu_clks: count of clocks in @cpu_clks
335   * @clk_regs: list of clock registers
336   * @nr_clk_regs: count of clock registers in @clk_regs
337   * @suspend_regs: list of clock registers to set before suspend
338   * @nr_suspend_regs: count of clock registers in @suspend_regs
339   * @clk_name: name of the parent clock needed for CMU register access
340   * @manual_plls: Enable manual control for PLL clocks
341   */
342  struct samsung_cmu_info {
343  	const struct samsung_pll_clock *pll_clks;
344  	unsigned int nr_pll_clks;
345  	const struct samsung_mux_clock *mux_clks;
346  	unsigned int nr_mux_clks;
347  	const struct samsung_div_clock *div_clks;
348  	unsigned int nr_div_clks;
349  	const struct samsung_gate_clock *gate_clks;
350  	unsigned int nr_gate_clks;
351  	const struct samsung_fixed_rate_clock *fixed_clks;
352  	unsigned int nr_fixed_clks;
353  	const struct samsung_fixed_factor_clock *fixed_factor_clks;
354  	unsigned int nr_fixed_factor_clks;
355  	unsigned int nr_clk_ids;
356  	const struct samsung_cpu_clock *cpu_clks;
357  	unsigned int nr_cpu_clks;
358  
359  	const unsigned long *clk_regs;
360  	unsigned int nr_clk_regs;
361  
362  	const struct samsung_clk_reg_dump *suspend_regs;
363  	unsigned int nr_suspend_regs;
364  	const char *clk_name;
365  
366  	/* ARM64 Exynos CMUs */
367  	bool manual_plls;
368  };
369  
370  struct samsung_clk_provider *samsung_clk_init(struct device *dev,
371  			void __iomem *base, unsigned long nr_clks);
372  void samsung_clk_of_add_provider(struct device_node *np,
373  			struct samsung_clk_provider *ctx);
374  void samsung_clk_of_register_fixed_ext(
375  			struct samsung_clk_provider *ctx,
376  			struct samsung_fixed_rate_clock *fixed_rate_clk,
377  			unsigned int nr_fixed_rate_clk,
378  			const struct of_device_id *clk_matches);
379  
380  void samsung_clk_add_lookup(struct samsung_clk_provider *ctx,
381  			struct clk_hw *clk_hw, unsigned int id);
382  
383  void samsung_clk_register_alias(struct samsung_clk_provider *ctx,
384  			const struct samsung_clock_alias *list,
385  			unsigned int nr_clk);
386  void samsung_clk_register_fixed_rate(
387  			struct samsung_clk_provider *ctx,
388  			const struct samsung_fixed_rate_clock *clk_list,
389  			unsigned int nr_clk);
390  void samsung_clk_register_fixed_factor(
391  			struct samsung_clk_provider *ctx,
392  			const struct samsung_fixed_factor_clock *list,
393  			unsigned int nr_clk);
394  void samsung_clk_register_mux(struct samsung_clk_provider *ctx,
395  			const struct samsung_mux_clock *clk_list,
396  			unsigned int nr_clk);
397  void samsung_clk_register_div(struct samsung_clk_provider *ctx,
398  			const struct samsung_div_clock *clk_list,
399  			unsigned int nr_clk);
400  void samsung_clk_register_gate(struct samsung_clk_provider *ctx,
401  			const struct samsung_gate_clock *clk_list,
402  			unsigned int nr_clk);
403  void samsung_clk_register_pll(struct samsung_clk_provider *ctx,
404  			const struct samsung_pll_clock *pll_list,
405  			unsigned int nr_clk);
406  void samsung_clk_register_cpu(struct samsung_clk_provider *ctx,
407  		const struct samsung_cpu_clock *list, unsigned int nr_clk);
408  
409  void samsung_cmu_register_clocks(struct samsung_clk_provider *ctx,
410  				 const struct samsung_cmu_info *cmu);
411  struct samsung_clk_provider *samsung_cmu_register_one(
412  			struct device_node *,
413  			const struct samsung_cmu_info *);
414  
415  #ifdef CONFIG_PM_SLEEP
416  void samsung_clk_extended_sleep_init(void __iomem *reg_base,
417  			const unsigned long *rdump,
418  			unsigned long nr_rdump,
419  			const struct samsung_clk_reg_dump *rsuspend,
420  			unsigned long nr_rsuspend);
421  #else
samsung_clk_extended_sleep_init(void __iomem * reg_base,const unsigned long * rdump,unsigned long nr_rdump,const struct samsung_clk_reg_dump * rsuspend,unsigned long nr_rsuspend)422  static inline void samsung_clk_extended_sleep_init(void __iomem *reg_base,
423  			const unsigned long *rdump,
424  			unsigned long nr_rdump,
425  			const struct samsung_clk_reg_dump *rsuspend,
426  			unsigned long nr_rsuspend) {}
427  #endif
428  #define samsung_clk_sleep_init(reg_base, rdump, nr_rdump) \
429  	samsung_clk_extended_sleep_init(reg_base, rdump, nr_rdump, NULL, 0)
430  
431  void samsung_clk_save(void __iomem *base,
432  			struct samsung_clk_reg_dump *rd,
433  			unsigned int num_regs);
434  void samsung_clk_restore(void __iomem *base,
435  			const struct samsung_clk_reg_dump *rd,
436  			unsigned int num_regs);
437  struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump(
438  			const unsigned long *rdump,
439  			unsigned long nr_rdump);
440  
441  #endif /* __SAMSUNG_CLK_H */
442