blob: 30ddbc1ced2ee82b31357c3c537ef6becd51ee97 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef __MACH_IMX_CLK_H
3#define __MACH_IMX_CLK_H
4
5#include <linux/spinlock.h>
6#include <linux/clk-provider.h>
7
8extern spinlock_t imx_ccm_lock;
9
10void imx_check_clocks(struct clk *clks[], unsigned int count);
11void imx_check_clk_hws(struct clk_hw *clks[], unsigned int count);
12void imx_register_uart_clocks(struct clk ** const clks[]);
13void imx_mmdc_mask_handshake(void __iomem *ccm_base, unsigned int chn);
14void imx_unregister_clocks(struct clk *clks[], unsigned int count);
15
16extern void imx_cscmr1_fixup(u32 *val);
17
18enum imx_pllv1_type {
19 IMX_PLLV1_IMX1,
20 IMX_PLLV1_IMX21,
21 IMX_PLLV1_IMX25,
22 IMX_PLLV1_IMX27,
23 IMX_PLLV1_IMX31,
24 IMX_PLLV1_IMX35,
25};
26
27enum imx_sccg_pll_type {
28 SCCG_PLL1,
29 SCCG_PLL2,
30};
31
32enum imx_pll14xx_type {
33 PLL_1416X,
34 PLL_1443X,
35};
36
37/* NOTE: Rate table should be kept sorted in descending order. */
38struct imx_pll14xx_rate_table {
39 unsigned int rate;
40 unsigned int pdiv;
41 unsigned int mdiv;
42 unsigned int sdiv;
43 unsigned int kdiv;
44};
45
46struct imx_pll14xx_clk {
47 enum imx_pll14xx_type type;
48 const struct imx_pll14xx_rate_table *rate_table;
49 int rate_count;
50 int flags;
51};
52
53extern struct imx_pll14xx_clk imx_1416x_pll;
54extern struct imx_pll14xx_clk imx_1443x_pll;
55
56#define imx_clk_cpu(name, parent_name, div, mux, pll, step) \
57 to_clk(imx_clk_hw_cpu(name, parent_name, div, mux, pll, step))
58
59#define clk_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \
60 cgr_val, clk_gate_flags, lock, share_count) \
61 to_clk(clk_hw_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \
62 cgr_val, clk_gate_flags, lock, share_count))
63
64#define imx_clk_pllv3(type, name, parent_name, base, div_mask) \
65 to_clk(imx_clk_hw_pllv3(type, name, parent_name, base, div_mask))
66
67#define imx_clk_pfd(name, parent_name, reg, idx) \
68 to_clk(imx_clk_hw_pfd(name, parent_name, reg, idx))
69
70#define imx_clk_gate_exclusive(name, parent, reg, shift, exclusive_mask) \
71 to_clk(imx_clk_hw_gate_exclusive(name, parent, reg, shift, exclusive_mask))
72
73#define imx_clk_fixed_factor(name, parent, mult, div) \
74 to_clk(imx_clk_hw_fixed_factor(name, parent, mult, div))
75
76#define imx_clk_divider2(name, parent, reg, shift, width) \
77 to_clk(imx_clk_hw_divider2(name, parent, reg, shift, width))
78
79#define imx_clk_gate_dis(name, parent, reg, shift) \
80 to_clk(imx_clk_hw_gate_dis(name, parent, reg, shift))
81
82#define imx_clk_gate2(name, parent, reg, shift) \
83 to_clk(imx_clk_hw_gate2(name, parent, reg, shift))
84
85#define imx_clk_gate2_flags(name, parent, reg, shift, flags) \
86 to_clk(imx_clk_hw_gate2_flags(name, parent, reg, shift, flags))
87
88#define imx_clk_gate2_shared2(name, parent, reg, shift, share_count) \
89 to_clk(imx_clk_hw_gate2_shared2(name, parent, reg, shift, share_count))
90
91#define imx_clk_gate3(name, parent, reg, shift) \
92 to_clk(imx_clk_hw_gate3(name, parent, reg, shift))
93
94#define imx_clk_gate4(name, parent, reg, shift) \
95 to_clk(imx_clk_hw_gate4(name, parent, reg, shift))
96
97#define imx_clk_mux(name, reg, shift, width, parents, num_parents) \
98 to_clk(imx_clk_hw_mux(name, reg, shift, width, parents, num_parents))
99
100struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
101 void __iomem *base, const struct imx_pll14xx_clk *pll_clk);
102
103struct clk *imx_clk_pllv1(enum imx_pllv1_type type, const char *name,
104 const char *parent, void __iomem *base);
105
106struct clk *imx_clk_pllv2(const char *name, const char *parent,
107 void __iomem *base);
108
109struct clk *imx_clk_frac_pll(const char *name, const char *parent_name,
110 void __iomem *base);
111
112struct clk *imx_clk_sccg_pll(const char *name,
113 const char * const *parent_names,
114 u8 num_parents,
115 u8 parent, u8 bypass1, u8 bypass2,
116 void __iomem *base,
117 unsigned long flags);
118
119enum imx_pllv3_type {
120 IMX_PLLV3_GENERIC,
121 IMX_PLLV3_SYS,
122 IMX_PLLV3_USB,
123 IMX_PLLV3_USB_VF610,
124 IMX_PLLV3_AV,
125 IMX_PLLV3_ENET,
126 IMX_PLLV3_ENET_IMX7,
127 IMX_PLLV3_SYS_VF610,
128 IMX_PLLV3_DDR_IMX7,
129 IMX_PLLV3_AV_IMX7,
130};
131
132struct clk_hw *imx_clk_hw_pllv3(enum imx_pllv3_type type, const char *name,
133 const char *parent_name, void __iomem *base, u32 div_mask);
134
135#define PLL_1416X_RATE(_rate, _m, _p, _s) \
136 { \
137 .rate = (_rate), \
138 .mdiv = (_m), \
139 .pdiv = (_p), \
140 .sdiv = (_s), \
141 }
142
143#define PLL_1443X_RATE(_rate, _m, _p, _s, _k) \
144 { \
145 .rate = (_rate), \
146 .mdiv = (_m), \
147 .pdiv = (_p), \
148 .sdiv = (_s), \
149 .kdiv = (_k), \
150 }
151
152struct clk_hw *imx_clk_pllv4(const char *name, const char *parent_name,
153 void __iomem *base);
154
155struct clk_hw *clk_hw_register_gate2(struct device *dev, const char *name,
156 const char *parent_name, unsigned long flags,
157 void __iomem *reg, u8 bit_idx, u8 cgr_val,
158 u8 clk_gate_flags, spinlock_t *lock,
159 unsigned int *share_count);
160
161struct clk * imx_obtain_fixed_clock(
162 const char *name, unsigned long rate);
163
164struct clk_hw *imx_obtain_fixed_clock_hw(
165 const char *name, unsigned long rate);
166
167struct clk_hw *imx_obtain_fixed_clk_hw(struct device_node *np,
168 const char *name);
169
170struct clk_hw *imx_clk_hw_gate_exclusive(const char *name, const char *parent,
171 void __iomem *reg, u8 shift, u32 exclusive_mask);
172
173struct clk_hw *imx_clk_hw_pfd(const char *name, const char *parent_name,
174 void __iomem *reg, u8 idx);
175
176struct clk_hw *imx_clk_pfdv2(const char *name, const char *parent_name,
177 void __iomem *reg, u8 idx);
178
179struct clk_hw *imx_clk_hw_busy_divider(const char *name, const char *parent_name,
180 void __iomem *reg, u8 shift, u8 width,
181 void __iomem *busy_reg, u8 busy_shift);
182
183struct clk_hw *imx_clk_hw_busy_mux(const char *name, void __iomem *reg, u8 shift,
184 u8 width, void __iomem *busy_reg, u8 busy_shift,
185 const char * const *parent_names, int num_parents);
186
187struct clk_hw *imx7ulp_clk_composite(const char *name,
188 const char * const *parent_names,
189 int num_parents, bool mux_present,
190 bool rate_present, bool gate_present,
191 void __iomem *reg);
192
193struct clk_hw *imx_clk_hw_fixup_divider(const char *name, const char *parent,
194 void __iomem *reg, u8 shift, u8 width,
195 void (*fixup)(u32 *val));
196
197struct clk_hw *imx_clk_hw_fixup_mux(const char *name, void __iomem *reg,
198 u8 shift, u8 width, const char * const *parents,
199 int num_parents, void (*fixup)(u32 *val));
200
201static inline struct clk *to_clk(struct clk_hw *hw)
202{
203 if (IS_ERR_OR_NULL(hw))
204 return ERR_CAST(hw);
205 return hw->clk;
206}
207
208static inline struct clk *imx_clk_fixed(const char *name, int rate)
209{
210 return clk_register_fixed_rate(NULL, name, NULL, 0, rate);
211}
212
213static inline struct clk_hw *imx_clk_hw_fixed(const char *name, int rate)
214{
215 return clk_hw_register_fixed_rate(NULL, name, NULL, 0, rate);
216}
217
218static inline struct clk_hw *imx_clk_hw_mux_ldb(const char *name, void __iomem *reg,
219 u8 shift, u8 width, const char * const *parents,
220 int num_parents)
221{
222 return clk_hw_register_mux(NULL, name, parents, num_parents,
223 CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT, reg,
224 shift, width, CLK_MUX_READ_ONLY, &imx_ccm_lock);
225}
226
227static inline struct clk_hw *imx_clk_hw_fixed_factor(const char *name,
228 const char *parent, unsigned int mult, unsigned int div)
229{
230 return clk_hw_register_fixed_factor(NULL, name, parent,
231 CLK_SET_RATE_PARENT, mult, div);
232}
233
234static inline struct clk *imx_clk_divider(const char *name, const char *parent,
235 void __iomem *reg, u8 shift, u8 width)
236{
237 return clk_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT,
238 reg, shift, width, 0, &imx_ccm_lock);
239}
240
241static inline struct clk_hw *imx_clk_hw_divider(const char *name,
242 const char *parent,
243 void __iomem *reg, u8 shift,
244 u8 width)
245{
246 return clk_hw_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT,
247 reg, shift, width, 0, &imx_ccm_lock);
248}
249
250static inline struct clk *imx_clk_divider_flags(const char *name,
251 const char *parent, void __iomem *reg, u8 shift, u8 width,
252 unsigned long flags)
253{
254 return clk_register_divider(NULL, name, parent, flags,
255 reg, shift, width, 0, &imx_ccm_lock);
256}
257
258static inline struct clk_hw *imx_clk_hw_divider_flags(const char *name,
259 const char *parent,
260 void __iomem *reg, u8 shift,
261 u8 width, unsigned long flags)
262{
263 return clk_hw_register_divider(NULL, name, parent, flags,
264 reg, shift, width, 0, &imx_ccm_lock);
265}
266
267static inline struct clk_hw *imx_clk_hw_divider2(const char *name, const char *parent,
268 void __iomem *reg, u8 shift, u8 width)
269{
270 return clk_hw_register_divider(NULL, name, parent,
271 CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
272 reg, shift, width, 0, &imx_ccm_lock);
273}
274
275static inline struct clk *imx_clk_divider2_flags(const char *name,
276 const char *parent, void __iomem *reg, u8 shift, u8 width,
277 unsigned long flags)
278{
279 return clk_register_divider(NULL, name, parent,
280 flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
281 reg, shift, width, 0, &imx_ccm_lock);
282}
283
284static inline struct clk *imx_clk_gate(const char *name, const char *parent,
285 void __iomem *reg, u8 shift)
286{
287 return clk_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
288 shift, 0, &imx_ccm_lock);
289}
290
291static inline struct clk_hw *imx_clk_hw_gate_flags(const char *name, const char *parent,
292 void __iomem *reg, u8 shift, unsigned long flags)
293{
294 return clk_hw_register_gate(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg,
295 shift, 0, &imx_ccm_lock);
296}
297
298static inline struct clk_hw *imx_clk_hw_gate(const char *name, const char *parent,
299 void __iomem *reg, u8 shift)
300{
301 return clk_hw_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
302 shift, 0, &imx_ccm_lock);
303}
304
305static inline struct clk_hw *imx_clk_hw_gate_dis(const char *name, const char *parent,
306 void __iomem *reg, u8 shift)
307{
308 return clk_hw_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
309 shift, CLK_GATE_SET_TO_DISABLE, &imx_ccm_lock);
310}
311
312static inline struct clk_hw *imx_clk_hw_gate_dis_flags(const char *name, const char *parent,
313 void __iomem *reg, u8 shift, unsigned long flags)
314{
315 return clk_hw_register_gate(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg,
316 shift, CLK_GATE_SET_TO_DISABLE, &imx_ccm_lock);
317}
318
319static inline struct clk_hw *imx_clk_hw_gate2(const char *name, const char *parent,
320 void __iomem *reg, u8 shift)
321{
322 return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
323 shift, 0x3, 0, &imx_ccm_lock, NULL);
324}
325
326static inline struct clk_hw *imx_clk_hw_gate2_flags(const char *name, const char *parent,
327 void __iomem *reg, u8 shift, unsigned long flags)
328{
329 return clk_hw_register_gate2(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg,
330 shift, 0x3, 0, &imx_ccm_lock, NULL);
331}
332
333static inline struct clk_hw *imx_clk_hw_gate2_shared(const char *name,
334 const char *parent, void __iomem *reg, u8 shift,
335 unsigned int *share_count)
336{
337 return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
338 shift, 0x3, 0, &imx_ccm_lock, share_count);
339}
340
341static inline struct clk_hw *imx_clk_hw_gate2_shared2(const char *name,
342 const char *parent, void __iomem *reg, u8 shift,
343 unsigned int *share_count)
344{
345 return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT |
346 CLK_OPS_PARENT_ENABLE, reg, shift, 0x3, 0,
347 &imx_ccm_lock, share_count);
348}
349
350static inline struct clk *imx_clk_gate2_cgr(const char *name,
351 const char *parent, void __iomem *reg, u8 shift, u8 cgr_val)
352{
353 return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
354 shift, cgr_val, 0, &imx_ccm_lock, NULL);
355}
356
357static inline struct clk_hw *imx_clk_hw_gate3(const char *name, const char *parent,
358 void __iomem *reg, u8 shift)
359{
360 return clk_hw_register_gate(NULL, name, parent,
361 CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
362 reg, shift, 0, &imx_ccm_lock);
363}
364
365static inline struct clk *imx_clk_gate3_flags(const char *name,
366 const char *parent, void __iomem *reg, u8 shift,
367 unsigned long flags)
368{
369 return clk_register_gate(NULL, name, parent,
370 flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
371 reg, shift, 0, &imx_ccm_lock);
372}
373
374static inline struct clk_hw *imx_clk_hw_gate4(const char *name, const char *parent,
375 void __iomem *reg, u8 shift)
376{
377 return clk_hw_register_gate2(NULL, name, parent,
378 CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
379 reg, shift, 0x3, 0, &imx_ccm_lock, NULL);
380}
381
382static inline struct clk *imx_clk_gate4_flags(const char *name,
383 const char *parent, void __iomem *reg, u8 shift,
384 unsigned long flags)
385{
386 return clk_register_gate2(NULL, name, parent,
387 flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
388 reg, shift, 0x3, 0, &imx_ccm_lock, NULL);
389}
390
391static inline struct clk_hw *imx_clk_hw_mux(const char *name, void __iomem *reg,
392 u8 shift, u8 width, const char * const *parents,
393 int num_parents)
394{
395 return clk_hw_register_mux(NULL, name, parents, num_parents,
396 CLK_SET_RATE_NO_REPARENT, reg, shift,
397 width, 0, &imx_ccm_lock);
398}
399
400static inline struct clk *imx_clk_mux2(const char *name, void __iomem *reg,
401 u8 shift, u8 width, const char * const *parents,
402 int num_parents)
403{
404 return clk_register_mux(NULL, name, parents, num_parents,
405 CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE,
406 reg, shift, width, 0, &imx_ccm_lock);
407}
408
409static inline struct clk_hw *imx_clk_hw_mux2(const char *name, void __iomem *reg,
410 u8 shift, u8 width,
411 const char * const *parents,
412 int num_parents)
413{
414 return clk_hw_register_mux(NULL, name, parents, num_parents,
415 CLK_SET_RATE_NO_REPARENT |
416 CLK_OPS_PARENT_ENABLE,
417 reg, shift, width, 0, &imx_ccm_lock);
418}
419
420static inline struct clk *imx_clk_mux_flags(const char *name,
421 void __iomem *reg, u8 shift, u8 width,
422 const char * const *parents, int num_parents,
423 unsigned long flags)
424{
425 return clk_register_mux(NULL, name, parents, num_parents,
426 flags | CLK_SET_RATE_NO_REPARENT, reg, shift, width, 0,
427 &imx_ccm_lock);
428}
429
430static inline struct clk *imx_clk_mux2_flags(const char *name,
431 void __iomem *reg, u8 shift, u8 width,
432 const char * const *parents,
433 int num_parents, unsigned long flags)
434{
435 return clk_register_mux(NULL, name, parents, num_parents,
436 flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE,
437 reg, shift, width, 0, &imx_ccm_lock);
438}
439
440static inline struct clk_hw *imx_clk_hw_mux_flags(const char *name,
441 void __iomem *reg, u8 shift,
442 u8 width,
443 const char * const *parents,
444 int num_parents,
445 unsigned long flags)
446{
447 return clk_hw_register_mux(NULL, name, parents, num_parents,
448 flags | CLK_SET_RATE_NO_REPARENT,
449 reg, shift, width, 0, &imx_ccm_lock);
450}
451
452struct clk_hw *imx_clk_hw_cpu(const char *name, const char *parent_name,
453 struct clk *div, struct clk *mux, struct clk *pll,
454 struct clk *step);
455
456struct clk *imx8m_clk_composite_flags(const char *name,
457 const char * const *parent_names,
458 int num_parents, void __iomem *reg,
459 unsigned long flags);
460
461#define __imx8m_clk_composite(name, parent_names, reg, flags) \
462 imx8m_clk_composite_flags(name, parent_names, \
463 ARRAY_SIZE(parent_names), reg, \
464 flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
465
466#define imx8m_clk_composite(name, parent_names, reg) \
467 __imx8m_clk_composite(name, parent_names, reg, 0)
468
469#define imx8m_clk_composite_critical(name, parent_names, reg) \
470 __imx8m_clk_composite(name, parent_names, reg, CLK_IS_CRITICAL)
471
472struct clk_hw *imx_clk_divider_gate(const char *name, const char *parent_name,
473 unsigned long flags, void __iomem *reg, u8 shift, u8 width,
474 u8 clk_divider_flags, const struct clk_div_table *table,
475 spinlock_t *lock);
476#endif