1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef __MACH_IMX_CLK_H
3 #define __MACH_IMX_CLK_H
5 #include <linux/spinlock.h>
6 #include <linux/clk-provider.h>
8 extern spinlock_t imx_ccm_lock
;
10 void imx_check_clocks(struct clk
*clks
[], unsigned int count
);
11 void imx_check_clk_hws(struct clk_hw
*clks
[], unsigned int count
);
12 void imx_register_uart_clocks(struct clk
** const clks
[]);
13 void imx_mmdc_mask_handshake(void __iomem
*ccm_base
, unsigned int chn
);
14 void imx_unregister_clocks(struct clk
*clks
[], unsigned int count
);
15 void imx_unregister_hw_clocks(struct clk_hw
*hws
[], unsigned int count
);
17 extern void imx_cscmr1_fixup(u32
*val
);
28 enum imx_sscg_pll_type
{
33 enum imx_pll14xx_type
{
38 /* NOTE: Rate table should be kept sorted in descending order. */
39 struct imx_pll14xx_rate_table
{
47 struct imx_pll14xx_clk
{
48 enum imx_pll14xx_type type
;
49 const struct imx_pll14xx_rate_table
*rate_table
;
54 extern struct imx_pll14xx_clk imx_1416x_pll
;
55 extern struct imx_pll14xx_clk imx_1443x_pll
;
56 extern struct imx_pll14xx_clk imx_1443x_dram_pll
;
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))
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))
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))
69 #define imx_clk_pfd(name, parent_name, reg, idx) \
70 to_clk(imx_clk_hw_pfd(name, parent_name, reg, idx))
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))
75 #define imx_clk_fixed(name, rate) \
76 to_clk(imx_clk_hw_fixed(name, rate))
78 #define imx_clk_fixed_factor(name, parent, mult, div) \
79 to_clk(imx_clk_hw_fixed_factor(name, parent, mult, div))
81 #define imx_clk_divider(name, parent, reg, shift, width) \
82 to_clk(imx_clk_hw_divider(name, parent, reg, shift, width))
84 #define imx_clk_divider2(name, parent, reg, shift, width) \
85 to_clk(imx_clk_hw_divider2(name, parent, reg, shift, width))
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))
90 #define imx_clk_gate(name, parent, reg, shift) \
91 to_clk(imx_clk_hw_gate(name, parent, reg, shift))
93 #define imx_clk_gate_dis(name, parent, reg, shift) \
94 to_clk(imx_clk_hw_gate_dis(name, parent, reg, shift))
96 #define imx_clk_gate2(name, parent, reg, shift) \
97 to_clk(imx_clk_hw_gate2(name, parent, reg, shift))
99 #define imx_clk_gate2_flags(name, parent, reg, shift, flags) \
100 to_clk(imx_clk_hw_gate2_flags(name, parent, reg, shift, flags))
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))
105 #define imx_clk_gate3(name, parent, reg, shift) \
106 to_clk(imx_clk_hw_gate3(name, parent, reg, shift))
108 #define imx_clk_gate4(name, parent, reg, shift) \
109 to_clk(imx_clk_hw_gate4(name, parent, reg, shift))
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))
114 #define imx_clk_pllv1(type, name, parent, base) \
115 to_clk(imx_clk_hw_pllv1(type, name, parent, base))
117 #define imx_clk_pllv2(name, parent, base) \
118 to_clk(imx_clk_hw_pllv2(name, parent, base))
120 #define imx_clk_frac_pll(name, parent_name, base) \
121 to_clk(imx_clk_hw_frac_pll(name, parent_name, base))
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))
128 struct clk
*imx_clk_pll14xx(const char *name
, const char *parent_name
,
129 void __iomem
*base
, const struct imx_pll14xx_clk
*pll_clk
);
131 #define imx_clk_pll14xx(name, parent_name, base, pll_clk) \
132 to_clk(imx_clk_hw_pll14xx(name, parent_name, base, pll_clk))
134 struct clk_hw
*imx_clk_hw_pll14xx(const char *name
, const char *parent_name
,
136 const struct imx_pll14xx_clk
*pll_clk
);
138 struct clk_hw
*imx_clk_hw_pllv1(enum imx_pllv1_type type
, const char *name
,
139 const char *parent
, void __iomem
*base
);
141 struct clk_hw
*imx_clk_hw_pllv2(const char *name
, const char *parent
,
144 struct clk_hw
*imx_clk_hw_frac_pll(const char *name
, const char *parent_name
,
147 struct clk_hw
*imx_clk_hw_sscg_pll(const char *name
,
148 const char * const *parent_names
,
150 u8 parent
, u8 bypass1
, u8 bypass2
,
152 unsigned long flags
);
154 enum imx_pllv3_type
{
167 struct 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
);
170 #define PLL_1416X_RATE(_rate, _m, _p, _s) \
178 #define PLL_1443X_RATE(_rate, _m, _p, _s, _k) \
187 struct clk_hw
*imx_clk_hw_pllv4(const char *name
, const char *parent_name
,
190 struct 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
);
196 struct clk
* imx_obtain_fixed_clock(
197 const char *name
, unsigned long rate
);
199 struct clk_hw
*imx_obtain_fixed_clock_hw(
200 const char *name
, unsigned long rate
);
202 struct clk_hw
*imx_obtain_fixed_clk_hw(struct device_node
*np
,
205 struct clk_hw
*imx_clk_hw_gate_exclusive(const char *name
, const char *parent
,
206 void __iomem
*reg
, u8 shift
, u32 exclusive_mask
);
208 struct clk_hw
*imx_clk_hw_pfd(const char *name
, const char *parent_name
,
209 void __iomem
*reg
, u8 idx
);
211 struct clk_hw
*imx_clk_hw_pfdv2(const char *name
, const char *parent_name
,
212 void __iomem
*reg
, u8 idx
);
214 struct 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
);
218 struct 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
);
222 struct 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
,
228 struct 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
));
232 struct 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
));
236 static inline struct clk
*to_clk(struct clk_hw
*hw
)
238 if (IS_ERR_OR_NULL(hw
))
243 static inline struct clk_hw
*imx_clk_hw_fixed(const char *name
, int rate
)
245 return clk_hw_register_fixed_rate(NULL
, name
, NULL
, 0, rate
);
248 static inline struct clk_hw
*imx_clk_hw_mux_ldb(const char *name
, void __iomem
*reg
,
249 u8 shift
, u8 width
, const char * const *parents
,
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
);
257 static inline struct clk_hw
*imx_clk_hw_fixed_factor(const char *name
,
258 const char *parent
, unsigned int mult
, unsigned int div
)
260 return clk_hw_register_fixed_factor(NULL
, name
, parent
,
261 CLK_SET_RATE_PARENT
, mult
, div
);
264 static inline struct clk_hw
*imx_clk_hw_divider(const char *name
,
266 void __iomem
*reg
, u8 shift
,
269 return clk_hw_register_divider(NULL
, name
, parent
, CLK_SET_RATE_PARENT
,
270 reg
, shift
, width
, 0, &imx_ccm_lock
);
273 static inline struct clk_hw
*imx_clk_hw_divider_flags(const char *name
,
275 void __iomem
*reg
, u8 shift
,
276 u8 width
, unsigned long flags
)
278 return clk_hw_register_divider(NULL
, name
, parent
, flags
,
279 reg
, shift
, width
, 0, &imx_ccm_lock
);
282 static inline struct clk_hw
*imx_clk_hw_divider2(const char *name
, const char *parent
,
283 void __iomem
*reg
, u8 shift
, u8 width
)
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
);
290 static inline struct clk
*imx_clk_divider2_flags(const char *name
,
291 const char *parent
, void __iomem
*reg
, u8 shift
, u8 width
,
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
);
299 static inline struct clk_hw
*imx_clk_hw_gate_flags(const char *name
, const char *parent
,
300 void __iomem
*reg
, u8 shift
, unsigned long flags
)
302 return clk_hw_register_gate(NULL
, name
, parent
, flags
| CLK_SET_RATE_PARENT
, reg
,
303 shift
, 0, &imx_ccm_lock
);
306 static inline struct clk_hw
*imx_clk_hw_gate(const char *name
, const char *parent
,
307 void __iomem
*reg
, u8 shift
)
309 return clk_hw_register_gate(NULL
, name
, parent
, CLK_SET_RATE_PARENT
, reg
,
310 shift
, 0, &imx_ccm_lock
);
313 static inline struct clk_hw
*imx_clk_hw_gate_dis(const char *name
, const char *parent
,
314 void __iomem
*reg
, u8 shift
)
316 return clk_hw_register_gate(NULL
, name
, parent
, CLK_SET_RATE_PARENT
, reg
,
317 shift
, CLK_GATE_SET_TO_DISABLE
, &imx_ccm_lock
);
320 static 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
)
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
);
327 static inline struct clk_hw
*imx_clk_hw_gate2(const char *name
, const char *parent
,
328 void __iomem
*reg
, u8 shift
)
330 return clk_hw_register_gate2(NULL
, name
, parent
, CLK_SET_RATE_PARENT
, reg
,
331 shift
, 0x3, 0, &imx_ccm_lock
, NULL
);
334 static inline struct clk_hw
*imx_clk_hw_gate2_flags(const char *name
, const char *parent
,
335 void __iomem
*reg
, u8 shift
, unsigned long flags
)
337 return clk_hw_register_gate2(NULL
, name
, parent
, flags
| CLK_SET_RATE_PARENT
, reg
,
338 shift
, 0x3, 0, &imx_ccm_lock
, NULL
);
341 static 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
)
345 return clk_hw_register_gate2(NULL
, name
, parent
, CLK_SET_RATE_PARENT
, reg
,
346 shift
, 0x3, 0, &imx_ccm_lock
, share_count
);
349 static 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
)
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
);
358 static inline struct clk
*imx_clk_gate2_cgr(const char *name
,
359 const char *parent
, void __iomem
*reg
, u8 shift
, u8 cgr_val
)
361 return clk_register_gate2(NULL
, name
, parent
, CLK_SET_RATE_PARENT
, reg
,
362 shift
, cgr_val
, 0, &imx_ccm_lock
, NULL
);
365 static inline struct clk_hw
*imx_clk_hw_gate3(const char *name
, const char *parent
,
366 void __iomem
*reg
, u8 shift
)
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
);
373 static inline struct clk_hw
*imx_clk_hw_gate3_flags(const char *name
,
374 const char *parent
, void __iomem
*reg
, u8 shift
,
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
);
382 #define imx_clk_gate3_flags(name, parent, reg, shift, flags) \
383 to_clk(imx_clk_hw_gate3_flags(name, parent, reg, shift, flags))
385 static inline struct clk_hw
*imx_clk_hw_gate4(const char *name
, const char *parent
,
386 void __iomem
*reg
, u8 shift
)
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
);
393 static inline struct clk_hw
*imx_clk_hw_gate4_flags(const char *name
,
394 const char *parent
, void __iomem
*reg
, u8 shift
,
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
);
402 #define imx_clk_gate4_flags(name, parent, reg, shift, flags) \
403 to_clk(imx_clk_hw_gate4_flags(name, parent, reg, shift, flags))
405 static inline struct clk_hw
*imx_clk_hw_mux(const char *name
, void __iomem
*reg
,
406 u8 shift
, u8 width
, const char * const *parents
,
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
);
414 static inline struct clk
*imx_clk_mux2(const char *name
, void __iomem
*reg
,
415 u8 shift
, u8 width
, const char * const *parents
,
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
);
423 static inline struct clk_hw
*imx_clk_hw_mux2(const char *name
, void __iomem
*reg
,
425 const char * const *parents
,
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
);
434 static 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
,
439 return clk_register_mux(NULL
, name
, parents
, num_parents
,
440 flags
| CLK_SET_RATE_NO_REPARENT
, reg
, shift
, width
, 0,
444 static 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
)
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
);
454 static 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
)
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
);
464 static inline struct clk_hw
*imx_clk_hw_mux_flags(const char *name
,
465 void __iomem
*reg
, u8 shift
,
467 const char * const *parents
,
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
);
476 struct clk_hw
*imx_clk_hw_cpu(const char *name
, const char *parent_name
,
477 struct clk
*div
, struct clk
*mux
, struct clk
*pll
,
480 #define IMX_COMPOSITE_CORE BIT(0)
482 struct clk_hw
*imx8m_clk_hw_composite_flags(const char *name
,
483 const char * const *parent_names
,
487 unsigned long flags
);
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)
495 #define imx8m_clk_composite_flags(name, parent_names, num_parents, reg, \
497 to_clk(imx8m_clk_hw_composite_flags(name, parent_names, \
498 num_parents, reg, 0, flags))
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)
505 #define __imx8m_clk_composite(name, parent_names, reg, flags) \
506 to_clk(__imx8m_clk_hw_composite(name, parent_names, reg, flags))
508 #define imx8m_clk_hw_composite(name, parent_names, reg) \
509 __imx8m_clk_hw_composite(name, parent_names, reg, 0)
511 #define imx8m_clk_composite(name, parent_names, reg) \
512 __imx8m_clk_composite(name, parent_names, reg, 0)
514 #define imx8m_clk_hw_composite_critical(name, parent_names, reg) \
515 __imx8m_clk_hw_composite(name, parent_names, reg, CLK_IS_CRITICAL)
517 #define imx8m_clk_composite_critical(name, parent_names, reg) \
518 __imx8m_clk_composite(name, parent_names, reg, CLK_IS_CRITICAL)
520 struct 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
,