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