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_register_uart_clocks_hws(struct clk_hw ** const hws[]);
14 void imx_mmdc_mask_handshake(void __iomem *ccm_base, unsigned int chn);
15 void imx_unregister_clocks(struct clk *clks[], unsigned int count);
17 extern void imx_cscmr1_fixup(u32 *val);
28 enum imx_sccg_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 #define imx_clk_busy_divider(name, parent_name, reg, shift, width, busy_reg, busy_shift) \
55 imx_clk_hw_busy_divider(name, parent_name, reg, shift, width, busy_reg, busy_shift)->clk
57 #define imx_clk_busy_mux(name, reg, shift, width, busy_reg, busy_shift, parent_names, num_parents) \
58 imx_clk_hw_busy_mux(name, reg, shift, width, busy_reg, busy_shift, parent_names, num_parents)->clk
60 #define imx_clk_cpu(name, parent_name, div, mux, pll, step) \
61 imx_clk_hw_cpu(name, parent_name, div, mux, pll, step)->clk
63 #define clk_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \
64 cgr_val, clk_gate_flags, lock, share_count) \
65 clk_hw_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \
66 cgr_val, clk_gate_flags, lock, share_count)->clk
68 #define imx_clk_pllv3(type, name, parent_name, base, div_mask) \
69 imx_clk_hw_pllv3(type, name, parent_name, base, div_mask)->clk
71 #define imx_clk_pfd(name, parent_name, reg, idx) \
72 imx_clk_hw_pfd(name, parent_name, reg, idx)->clk
74 #define imx_clk_gate_exclusive(name, parent, reg, shift, exclusive_mask) \
75 imx_clk_hw_gate_exclusive(name, parent, reg, shift, exclusive_mask)->clk
77 #define imx_clk_fixup_divider(name, parent, reg, shift, width, fixup) \
78 imx_clk_hw_fixup_divider(name, parent, reg, shift, width, fixup)->clk
80 #define imx_clk_fixup_mux(name, reg, shift, width, parents, num_parents, fixup) \
81 imx_clk_hw_fixup_mux(name, reg, shift, width, parents, num_parents, fixup)->clk
83 #define imx_clk_mux_ldb(name, reg, shift, width, parents, num_parents) \
84 imx_clk_hw_mux_ldb(name, reg, shift, width, parents, num_parents)->clk
86 #define imx_clk_fixed_factor(name, parent, mult, div) \
87 imx_clk_hw_fixed_factor(name, parent, mult, div)->clk
89 #define imx_clk_divider2(name, parent, reg, shift, width) \
90 imx_clk_hw_divider2(name, parent, reg, shift, width)->clk
92 #define imx_clk_gate_dis(name, parent, reg, shift) \
93 imx_clk_hw_gate_dis(name, parent, reg, shift)->clk
95 #define imx_clk_gate_dis_flags(name, parent, reg, shift, flags) \
96 imx_clk_hw_gate_dis_flags(name, parent, reg, shift, flags)->clk
98 #define imx_clk_gate_flags(name, parent, reg, shift, flags) \
99 imx_clk_hw_gate_flags(name, parent, reg, shift, flags)->clk
101 #define imx_clk_gate2(name, parent, reg, shift) \
102 imx_clk_hw_gate2(name, parent, reg, shift)->clk
104 #define imx_clk_gate2_flags(name, parent, reg, shift, flags) \
105 imx_clk_hw_gate2_flags(name, parent, reg, shift, flags)->clk
107 #define imx_clk_gate2_shared(name, parent, reg, shift, share_count) \
108 imx_clk_hw_gate2_shared(name, parent, reg, shift, share_count)->clk
110 #define imx_clk_gate2_shared2(name, parent, reg, shift, share_count) \
111 imx_clk_hw_gate2_shared2(name, parent, reg, shift, share_count)->clk
113 #define imx_clk_gate3(name, parent, reg, shift) \
114 imx_clk_hw_gate3(name, parent, reg, shift)->clk
116 #define imx_clk_gate4(name, parent, reg, shift) \
117 imx_clk_hw_gate4(name, parent, reg, shift)->clk
119 #define imx_clk_mux(name, reg, shift, width, parents, num_parents) \
120 imx_clk_hw_mux(name, reg, shift, width, parents, num_parents)->clk
122 struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
123 void __iomem *base, const struct imx_pll14xx_clk *pll_clk);
125 struct clk *imx_clk_pllv1(enum imx_pllv1_type type, const char *name,
126 const char *parent, void __iomem *base);
128 struct clk *imx_clk_pllv2(const char *name, const char *parent,
131 struct clk *imx_clk_frac_pll(const char *name, const char *parent_name,
134 struct clk *imx_clk_sccg_pll(const char *name,
135 const char * const *parent_names,
137 u8 parent, u8 bypass1, u8 bypass2,
139 unsigned long flags);
141 enum imx_pllv3_type {
154 struct clk_hw *imx_clk_hw_pllv3(enum imx_pllv3_type type, const char *name,
155 const char *parent_name, void __iomem *base, u32 div_mask);
157 #define PLL_1416X_RATE(_rate, _m, _p, _s) \
165 #define PLL_1443X_RATE(_rate, _m, _p, _s, _k) \
174 struct clk_hw *imx_clk_pllv4(const char *name, const char *parent_name,
177 struct clk_hw *clk_hw_register_gate2(struct device *dev, const char *name,
178 const char *parent_name, unsigned long flags,
179 void __iomem *reg, u8 bit_idx, u8 cgr_val,
180 u8 clk_gate_flags, spinlock_t *lock,
181 unsigned int *share_count);
183 struct clk * imx_obtain_fixed_clock(
184 const char *name, unsigned long rate);
186 struct clk_hw *imx_obtain_fixed_clock_hw(
187 const char *name, unsigned long rate);
189 struct clk_hw *imx_obtain_fixed_clk_hw(struct device_node *np,
192 struct clk_hw *imx_clk_hw_gate_exclusive(const char *name, const char *parent,
193 void __iomem *reg, u8 shift, u32 exclusive_mask);
195 struct clk_hw *imx_clk_hw_pfd(const char *name, const char *parent_name,
196 void __iomem *reg, u8 idx);
198 struct clk_hw *imx_clk_pfdv2(const char *name, const char *parent_name,
199 void __iomem *reg, u8 idx);
201 struct clk_hw *imx_clk_hw_busy_divider(const char *name, const char *parent_name,
202 void __iomem *reg, u8 shift, u8 width,
203 void __iomem *busy_reg, u8 busy_shift);
205 struct clk_hw *imx_clk_hw_busy_mux(const char *name, void __iomem *reg, u8 shift,
206 u8 width, void __iomem *busy_reg, u8 busy_shift,
207 const char * const *parent_names, int num_parents);
209 struct clk_hw *imx7ulp_clk_composite(const char *name,
210 const char * const *parent_names,
211 int num_parents, bool mux_present,
212 bool rate_present, bool gate_present,
215 struct clk_hw *imx_clk_hw_fixup_divider(const char *name, const char *parent,
216 void __iomem *reg, u8 shift, u8 width,
217 void (*fixup)(u32 *val));
219 struct clk_hw *imx_clk_hw_fixup_mux(const char *name, void __iomem *reg,
220 u8 shift, u8 width, const char * const *parents,
221 int num_parents, void (*fixup)(u32 *val));
223 static inline struct clk *imx_clk_fixed(const char *name, int rate)
225 return clk_register_fixed_rate(NULL, name, NULL, 0, rate);
228 static inline struct clk_hw *imx_clk_hw_fixed(const char *name, int rate)
230 return clk_hw_register_fixed_rate(NULL, name, NULL, 0, rate);
233 static inline struct clk_hw *imx_clk_hw_mux_ldb(const char *name, void __iomem *reg,
234 u8 shift, u8 width, const char * const *parents,
237 return clk_hw_register_mux(NULL, name, parents, num_parents,
238 CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT, reg,
239 shift, width, CLK_MUX_READ_ONLY, &imx_ccm_lock);
242 static inline struct clk_hw *imx_clk_hw_fixed_factor(const char *name,
243 const char *parent, unsigned int mult, unsigned int div)
245 return clk_hw_register_fixed_factor(NULL, name, parent,
246 CLK_SET_RATE_PARENT, mult, div);
249 static inline struct clk *imx_clk_divider(const char *name, const char *parent,
250 void __iomem *reg, u8 shift, u8 width)
252 return clk_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT,
253 reg, shift, width, 0, &imx_ccm_lock);
256 static inline struct clk_hw *imx_clk_hw_divider(const char *name,
258 void __iomem *reg, u8 shift,
261 return clk_hw_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT,
262 reg, shift, width, 0, &imx_ccm_lock);
265 static inline struct clk *imx_clk_divider_flags(const char *name,
266 const char *parent, void __iomem *reg, u8 shift, u8 width,
269 return clk_register_divider(NULL, name, parent, flags,
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 *imx_clk_gate(const char *name, const char *parent,
300 void __iomem *reg, u8 shift)
302 return clk_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
303 shift, 0, &imx_ccm_lock);
306 static inline struct clk_hw *imx_clk_hw_gate_flags(const char *name, const char *parent,
307 void __iomem *reg, u8 shift, unsigned long flags)
309 return clk_hw_register_gate(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg,
310 shift, 0, &imx_ccm_lock);
313 static inline struct clk_hw *imx_clk_hw_gate(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, 0, &imx_ccm_lock);
320 static inline struct clk_hw *imx_clk_hw_gate_dis(const char *name, const char *parent,
321 void __iomem *reg, u8 shift)
323 return clk_hw_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
324 shift, CLK_GATE_SET_TO_DISABLE, &imx_ccm_lock);
327 static inline struct clk_hw *imx_clk_hw_gate_dis_flags(const char *name, const char *parent,
328 void __iomem *reg, u8 shift, unsigned long flags)
330 return clk_hw_register_gate(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg,
331 shift, CLK_GATE_SET_TO_DISABLE, &imx_ccm_lock);
334 static inline struct clk_hw *imx_clk_hw_gate2(const char *name, const char *parent,
335 void __iomem *reg, u8 shift)
337 return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
338 shift, 0x3, 0, &imx_ccm_lock, NULL);
341 static inline struct clk_hw *imx_clk_hw_gate2_flags(const char *name, const char *parent,
342 void __iomem *reg, u8 shift, unsigned long flags)
344 return clk_hw_register_gate2(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg,
345 shift, 0x3, 0, &imx_ccm_lock, NULL);
348 static inline struct clk_hw *imx_clk_hw_gate2_shared(const char *name,
349 const char *parent, void __iomem *reg, u8 shift,
350 unsigned int *share_count)
352 return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
353 shift, 0x3, 0, &imx_ccm_lock, share_count);
356 static inline struct clk_hw *imx_clk_hw_gate2_shared2(const char *name,
357 const char *parent, void __iomem *reg, u8 shift,
358 unsigned int *share_count)
360 return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT |
361 CLK_OPS_PARENT_ENABLE, reg, shift, 0x3, 0,
362 &imx_ccm_lock, share_count);
365 static inline struct clk *imx_clk_gate2_cgr(const char *name,
366 const char *parent, void __iomem *reg, u8 shift, u8 cgr_val)
368 return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
369 shift, cgr_val, 0, &imx_ccm_lock, NULL);
372 static inline struct clk_hw *imx_clk_hw_gate3(const char *name, const char *parent,
373 void __iomem *reg, u8 shift)
375 return clk_hw_register_gate(NULL, name, parent,
376 CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
377 reg, shift, 0, &imx_ccm_lock);
380 static inline struct clk *imx_clk_gate3_flags(const char *name,
381 const char *parent, void __iomem *reg, u8 shift,
384 return clk_register_gate(NULL, name, parent,
385 flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
386 reg, shift, 0, &imx_ccm_lock);
389 static inline struct clk_hw *imx_clk_hw_gate4(const char *name, const char *parent,
390 void __iomem *reg, u8 shift)
392 return clk_hw_register_gate2(NULL, name, parent,
393 CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
394 reg, shift, 0x3, 0, &imx_ccm_lock, NULL);
397 static inline struct clk *imx_clk_gate4_flags(const char *name,
398 const char *parent, void __iomem *reg, u8 shift,
401 return clk_register_gate2(NULL, name, parent,
402 flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
403 reg, shift, 0x3, 0, &imx_ccm_lock, NULL);
406 static inline struct clk_hw *imx_clk_hw_mux(const char *name, void __iomem *reg,
407 u8 shift, u8 width, const char * const *parents,
410 return clk_hw_register_mux(NULL, name, parents, num_parents,
411 CLK_SET_RATE_NO_REPARENT, reg, shift,
412 width, 0, &imx_ccm_lock);
415 static inline struct clk *imx_clk_mux2(const char *name, void __iomem *reg,
416 u8 shift, u8 width, const char * const *parents,
419 return clk_register_mux(NULL, name, parents, num_parents,
420 CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE,
421 reg, shift, width, 0, &imx_ccm_lock);
424 static inline struct clk_hw *imx_clk_hw_mux2(const char *name, void __iomem *reg,
426 const char * const *parents,
429 return clk_hw_register_mux(NULL, name, parents, num_parents,
430 CLK_SET_RATE_NO_REPARENT |
431 CLK_OPS_PARENT_ENABLE,
432 reg, shift, width, 0, &imx_ccm_lock);
435 static inline struct clk *imx_clk_mux_flags(const char *name,
436 void __iomem *reg, u8 shift, u8 width,
437 const char * const *parents, int num_parents,
440 return clk_register_mux(NULL, name, parents, num_parents,
441 flags | CLK_SET_RATE_NO_REPARENT, reg, shift, width, 0,
445 static inline struct clk *imx_clk_mux2_flags(const char *name,
446 void __iomem *reg, u8 shift, u8 width,
447 const char * const *parents,
448 int num_parents, unsigned long flags)
450 return clk_register_mux(NULL, name, parents, num_parents,
451 flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE,
452 reg, shift, width, 0, &imx_ccm_lock);
455 static inline struct clk_hw *imx_clk_hw_mux_flags(const char *name,
456 void __iomem *reg, u8 shift,
458 const char * const *parents,
462 return clk_hw_register_mux(NULL, name, parents, num_parents,
463 flags | CLK_SET_RATE_NO_REPARENT,
464 reg, shift, width, 0, &imx_ccm_lock);
467 struct clk_hw *imx_clk_hw_cpu(const char *name, const char *parent_name,
468 struct clk *div, struct clk *mux, struct clk *pll,
471 struct clk *imx8m_clk_composite_flags(const char *name,
472 const char * const *parent_names,
473 int num_parents, void __iomem *reg,
474 unsigned long flags);
476 #define __imx8m_clk_composite(name, parent_names, reg, flags) \
477 imx8m_clk_composite_flags(name, parent_names, \
478 ARRAY_SIZE(parent_names), reg, \
479 flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
481 #define imx8m_clk_composite(name, parent_names, reg) \
482 __imx8m_clk_composite(name, parent_names, reg, 0)
484 #define imx8m_clk_composite_critical(name, parent_names, reg) \
485 __imx8m_clk_composite(name, parent_names, reg, CLK_IS_CRITICAL)
487 struct clk_hw *imx_clk_divider_gate(const char *name, const char *parent_name,
488 unsigned long flags, void __iomem *reg, u8 shift, u8 width,
489 u8 clk_divider_flags, const struct clk_div_table *table,