Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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
25enum eswin_clk_type {
26 CLK_FIXED_FACTOR,
27 CLK_MUX,
28 CLK_DIVIDER,
29 CLK_GATE,
30};
31
32struct 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
40struct 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
55struct 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
63struct 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
73struct 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
84struct 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
98struct 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
119struct 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
138struct 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
151struct eswin_clock_data *eswin_clk_init(struct platform_device *pdev,
152 size_t nr_clks);
153int eswin_clk_register_fixed_rate(struct device *dev,
154 struct eswin_fixed_rate_clock *clks,
155 int nums, struct eswin_clock_data *data);
156int eswin_clk_register_pll(struct device *dev, struct eswin_pll_clock *clks,
157 int nums, struct eswin_clock_data *data);
158int eswin_clk_register_fixed_factor(struct device *dev,
159 struct eswin_fixed_factor_clock *clks,
160 int nums, struct eswin_clock_data *data);
161int eswin_clk_register_mux(struct device *dev, struct eswin_mux_clock *clks,
162 int nums, struct eswin_clock_data *data);
163int eswin_clk_register_divider(struct device *dev,
164 struct eswin_divider_clock *clks,
165 int nums, struct eswin_clock_data *data);
166int eswin_clk_register_gate(struct device *dev, struct eswin_gate_clock *clks,
167 int nums, struct eswin_clock_data *data);
168int eswin_clk_register_clks(struct device *dev, struct eswin_clk_info *clks,
169 int nums, struct eswin_clock_data *data);
170struct 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__ */