xref: /linux/drivers/clk/eswin/common.h (revision 5ea5880764cbb164afb17a62e76ca75dc371409d)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright 2026, Beijing ESWIN Computing Technology Co., Ltd..
4  * All rights reserved.
5  *
6  * Authors:
7  *	Yifeng Huang <huangyifeng@eswincomputing.com>
8  *	Xuyang Dong <dongxuyang@eswincomputing.com>
9  */
10 
11 #ifndef __ESWIN_COMMON_H__
12 #define __ESWIN_COMMON_H__
13 
14 #define APLL_HIGH_FREQ	983040000
15 #define APLL_LOW_FREQ	225792000
16 #define PLL_HIGH_FREQ	1800000000
17 #define PLL_LOW_FREQ	24000000
18 
19 /*
20  * ESWIN_PRIV_DIV_MIN_2: If ESWIN_PRIV_DIV_MIN_2 is set, the minimum value of
21  *	the register is 2, i.e. the minimum division ratio is 2.
22  */
23 #define ESWIN_PRIV_DIV_MIN_2	BIT(0)
24 
25 enum eswin_clk_type {
26 	CLK_FIXED_FACTOR,
27 	CLK_MUX,
28 	CLK_DIVIDER,
29 	CLK_GATE,
30 };
31 
32 struct eswin_clock_data {
33 	void __iomem *base;
34 	struct clk_hw *original_clk;
35 	struct notifier_block pll_nb;
36 	spinlock_t lock; /* protect register read-modify-write cycle */
37 	struct clk_hw_onecell_data clk_data;
38 };
39 
40 struct eswin_divider_clock {
41 	struct clk_hw hw;
42 	unsigned int id;
43 	const char *name;
44 	const struct clk_parent_data *parent_data;
45 	void __iomem *ctrl_reg; /* register address of the divider clock */
46 	unsigned long flags;
47 	unsigned long reg; /* register offset */
48 	u8 shift;
49 	u8 width;
50 	unsigned long div_flags;
51 	unsigned long priv_flag;
52 	spinlock_t *lock; /* protect register read-modify-write cycle */
53 };
54 
55 struct eswin_fixed_rate_clock {
56 	struct clk_hw hw;
57 	unsigned int id;
58 	const char *name;
59 	unsigned long flags;
60 	unsigned long rate;
61 };
62 
63 struct eswin_fixed_factor_clock {
64 	struct clk_hw hw;
65 	unsigned int id;
66 	const char *name;
67 	const struct clk_parent_data *parent_data;
68 	unsigned long mult;
69 	unsigned long div;
70 	unsigned long flags;
71 };
72 
73 struct eswin_gate_clock {
74 	struct clk_hw hw;
75 	unsigned int id;
76 	const char *name;
77 	const struct clk_parent_data *parent_data;
78 	unsigned long flags;
79 	unsigned long reg;
80 	u8 bit_idx;
81 	u8 gate_flags;
82 };
83 
84 struct eswin_mux_clock {
85 	struct clk_hw hw;
86 	unsigned int id;
87 	const char *name;
88 	const struct clk_parent_data *parent_data;
89 	u8 num_parents;
90 	unsigned long flags;
91 	unsigned long reg;
92 	u8 shift;
93 	u8 width;
94 	u8 mux_flags;
95 	u32 *table;
96 };
97 
98 struct eswin_pll_clock {
99 	struct clk_hw hw;
100 	u32 id;
101 	const char *name;
102 	const struct clk_parent_data *parent_data;
103 	const u32 ctrl_reg0;
104 	const u8 fbdiv_shift;
105 
106 	const u32 ctrl_reg1;
107 	const u8 frac_shift;
108 
109 	const u32 ctrl_reg2;
110 
111 	const u32 status_reg;
112 	const u8 lock_shift;
113 	const u8 lock_width;
114 
115 	const u64 max_rate;
116 	const u64 min_rate;
117 };
118 
119 struct eswin_clk_pll {
120 	struct clk_hw hw;
121 	u32 id;
122 	void __iomem *ctrl_reg0;
123 	u8 fbdiv_shift;
124 
125 	void __iomem *ctrl_reg1;
126 	u8 frac_shift;
127 
128 	void __iomem *ctrl_reg2;
129 
130 	void __iomem *status_reg;
131 	u8 lock_shift;
132 	u8 lock_width;
133 
134 	u64 max_rate;
135 	u64 min_rate;
136 };
137 
138 struct eswin_clk_info {
139 	unsigned int type;
140 	unsigned int pid;
141 	unsigned int id;
142 	struct clk_hw hw;
143 	union {
144 		struct eswin_divider_clock div;
145 		struct eswin_fixed_factor_clock factor;
146 		struct eswin_gate_clock gate;
147 		struct eswin_mux_clock mux;
148 	} data;
149 };
150 
151 struct eswin_clock_data *eswin_clk_init(struct platform_device *pdev,
152 					size_t nr_clks);
153 int eswin_clk_register_fixed_rate(struct device *dev,
154 				  struct eswin_fixed_rate_clock *clks,
155 				  int nums, struct eswin_clock_data *data);
156 int eswin_clk_register_pll(struct device *dev, struct eswin_pll_clock *clks,
157 			   int nums, struct eswin_clock_data *data);
158 int eswin_clk_register_fixed_factor(struct device *dev,
159 				    struct eswin_fixed_factor_clock *clks,
160 				    int nums, struct eswin_clock_data *data);
161 int eswin_clk_register_mux(struct device *dev, struct eswin_mux_clock *clks,
162 			   int nums, struct eswin_clock_data *data);
163 int eswin_clk_register_divider(struct device *dev,
164 			       struct eswin_divider_clock *clks,
165 			       int nums, struct eswin_clock_data *data);
166 int eswin_clk_register_gate(struct device *dev, struct eswin_gate_clock *clks,
167 			    int nums, struct eswin_clock_data *data);
168 int eswin_clk_register_clks(struct device *dev, struct eswin_clk_info *clks,
169 			    int nums, struct eswin_clock_data *data);
170 struct clk_hw *eswin_register_clkdiv(struct device *dev, unsigned int id,
171 				     const char *name,
172 				     const struct clk_hw *parent_hw,
173 				     unsigned long flags, void __iomem *reg,
174 				     u8 shift, u8 width,
175 				     unsigned long clk_divider_flags,
176 				     unsigned long priv_flag, spinlock_t *lock);
177 
178 #define ESWIN_DIV(_id, _name, _pdata, _flags, _reg, _shift, _width,	\
179 		  _dflags, _pflag)					\
180 	{								\
181 		.id		= _id,					\
182 		.name		= _name,				\
183 		.parent_data	= _pdata,				\
184 		.flags		= _flags,				\
185 		.reg		= _reg,					\
186 		.shift		= _shift,				\
187 		.width		= _width,				\
188 		.div_flags	= _dflags,				\
189 		.priv_flag	= _pflag,				\
190 	}
191 
192 #define ESWIN_DIV_TYPE(_id, _name, _pid, _flags, _reg, _shift, _width,	\
193 		       _dflags, _pflag)					\
194 	{								\
195 		.type	= CLK_DIVIDER,					\
196 		.pid	= _pid,						\
197 		.id	= _id,						\
198 		.data	= {						\
199 				.div = {				\
200 					.name	= _name,		\
201 					.flags		= _flags,	\
202 					.reg		= _reg,		\
203 					.shift		= _shift,	\
204 					.width		= _width,	\
205 					.div_flags	= _dflags,	\
206 					.priv_flag	= _pflag,	\
207 				},					\
208 		},							\
209 	}
210 
211 #define ESWIN_FACTOR(_id, _name, _pdata, _mult, _div, _flags)		\
212 	{								\
213 		.id		= _id,					\
214 		.name		= _name,				\
215 		.parent_data	= _pdata,				\
216 		.mult		= _mult,				\
217 		.div		= _div,					\
218 		.flags		= _flags,				\
219 	}
220 
221 #define ESWIN_FACTOR_TYPE(_id, _name, _pid, _mult, _div, _flags)	\
222 	{								\
223 		.type	= CLK_FIXED_FACTOR,				\
224 		.pid	= _pid,						\
225 		.id	= _id,						\
226 		.data	= {						\
227 				.factor = {				\
228 					    .name	= _name,	\
229 					    .mult	= _mult,	\
230 					    .div	= _div,		\
231 					    .flags	= _flags,	\
232 				},					\
233 		},							\
234 	}
235 
236 #define ESWIN_FIXED(_id, _name, _flags, _rate)				\
237 	{								\
238 		.id		= _id,					\
239 		.name		= _name,				\
240 		.flags		= _flags,				\
241 		.rate		= _rate,				\
242 	}
243 
244 #define ESWIN_GATE(_id, _name, _pdata, _flags, _reg, _idx, _gflags)	\
245 	{								\
246 		.id		= _id,					\
247 		.name		= _name,				\
248 		.parent_data	= _pdata,				\
249 		.flags		= _flags,				\
250 		.reg		= _reg,					\
251 		.bit_idx	= _idx,					\
252 		.gate_flags	= _gflags,				\
253 	}
254 
255 #define ESWIN_GATE_TYPE(_id, _name, _pid, _flags, _reg, _idx, _gflags)	\
256 	{								\
257 		.type	= CLK_GATE,					\
258 		.pid	= _pid,						\
259 		.id	= _id,						\
260 		.data	= {						\
261 				.gate = {				\
262 					.name	= _name,		\
263 					.flags		= _flags,	\
264 					.reg		= _reg,		\
265 					.bit_idx	= _idx,		\
266 					.gate_flags	= _gflags,	\
267 				},					\
268 		},							\
269 	}
270 
271 #define ESWIN_MUX(_id, _name, _pdata, _num_parents, _flags, _reg,	\
272 		  _shift, _width, _mflags)				\
273 	{								\
274 		.id		= _id,					\
275 		.name		= _name,				\
276 		.parent_data	= _pdata,				\
277 		.num_parents	= _num_parents,				\
278 		.flags		= _flags,				\
279 		.reg		= _reg,					\
280 		.shift		= _shift,				\
281 		.width		= _width,				\
282 		.mux_flags	= _mflags,				\
283 		.table		= NULL,					\
284 	}
285 
286 #define ESWIN_MUX_TBL(_id, _name, _pdata, _num_parents, _flags, _reg,	\
287 		      _shift, _width, _mflags, _table)			\
288 	{								\
289 		.id		= _id,					\
290 		.name		= _name,				\
291 		.parent_data	= _pdata,				\
292 		.num_parents	= _num_parents,				\
293 		.flags		= _flags,				\
294 		.reg		= _reg,					\
295 		.shift		= _shift,				\
296 		.width		= _width,				\
297 		.mux_flags	= _mflags,				\
298 		.table		= _table,				\
299 	}
300 
301 #define ESWIN_MUX_TYPE(_id, _name, _pdata, _num_parents, _flags, _reg,	\
302 		       _shift, _width, _mflags, _table)			\
303 	{								\
304 		.type	= CLK_MUX,					\
305 		.id	= _id,						\
306 		.data	= {						\
307 				.mux = {				\
308 					.name	= _name,		\
309 					.parent_data	= _pdata,	\
310 					.num_parents	= _num_parents,	\
311 					.flags		= _flags,	\
312 					.reg		= _reg,		\
313 					.shift		= _shift,	\
314 					.width		= _width,	\
315 					.mux_flags	= _mflags,	\
316 					.table		= _table,	\
317 				},					\
318 		},							\
319 	}
320 
321 #define ESWIN_PLL(_id, _name, _pdata, _reg0, _fb_shift, _reg1,		\
322 		  _frac_shift, _reg2, _reg, _lock_shift, _lock_width,	\
323 		  _max_rate, _min_rate)					\
324 	{								\
325 		.id		= _id,					\
326 		.name		= _name,				\
327 		.parent_data	= _pdata,				\
328 		.ctrl_reg0	= _reg0,				\
329 		.fbdiv_shift	= _fb_shift,				\
330 		.ctrl_reg1	= _reg1,				\
331 		.frac_shift	= _frac_shift,				\
332 		.ctrl_reg2	= _reg2,				\
333 		.status_reg	= _reg,					\
334 		.lock_shift	= _lock_shift,				\
335 		.lock_width	= _lock_width,				\
336 		.max_rate	= _max_rate,				\
337 		.min_rate	= _min_rate,				\
338 	}
339 
340 #endif /* __ESWIN_COMMON_H__ */
341