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
);
16 extern void imx_cscmr1_fixup(u32
*val
);
27 enum imx_sccg_pll_type
{
32 enum imx_pll14xx_type
{
37 /* NOTE: Rate table should be kept sorted in descending order. */
38 struct imx_pll14xx_rate_table
{
46 struct imx_pll14xx_clk
{
47 enum imx_pll14xx_type type
;
48 const struct imx_pll14xx_rate_table
*rate_table
;
53 extern struct imx_pll14xx_clk imx_1416x_pll
;
54 extern struct imx_pll14xx_clk imx_1443x_pll
;
56 #define imx_clk_cpu(name, parent_name, div, mux, pll, step) \
57 imx_clk_hw_cpu(name, parent_name, div, mux, pll, step)->clk
59 #define clk_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \
60 cgr_val, clk_gate_flags, lock, share_count) \
61 clk_hw_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \
62 cgr_val, clk_gate_flags, lock, share_count)->clk
64 #define imx_clk_pllv3(type, name, parent_name, base, div_mask) \
65 imx_clk_hw_pllv3(type, name, parent_name, base, div_mask)->clk
67 #define imx_clk_pfd(name, parent_name, reg, idx) \
68 imx_clk_hw_pfd(name, parent_name, reg, idx)->clk
70 #define imx_clk_gate_exclusive(name, parent, reg, shift, exclusive_mask) \
71 imx_clk_hw_gate_exclusive(name, parent, reg, shift, exclusive_mask)->clk
73 #define imx_clk_fixed_factor(name, parent, mult, div) \
74 imx_clk_hw_fixed_factor(name, parent, mult, div)->clk
76 #define imx_clk_divider2(name, parent, reg, shift, width) \
77 imx_clk_hw_divider2(name, parent, reg, shift, width)->clk
79 #define imx_clk_gate_dis(name, parent, reg, shift) \
80 imx_clk_hw_gate_dis(name, parent, reg, shift)->clk
82 #define imx_clk_gate2(name, parent, reg, shift) \
83 imx_clk_hw_gate2(name, parent, reg, shift)->clk
85 #define imx_clk_gate2_flags(name, parent, reg, shift, flags) \
86 imx_clk_hw_gate2_flags(name, parent, reg, shift, flags)->clk
88 #define imx_clk_gate2_shared2(name, parent, reg, shift, share_count) \
89 imx_clk_hw_gate2_shared2(name, parent, reg, shift, share_count)->clk
91 #define imx_clk_gate3(name, parent, reg, shift) \
92 imx_clk_hw_gate3(name, parent, reg, shift)->clk
94 #define imx_clk_gate4(name, parent, reg, shift) \
95 imx_clk_hw_gate4(name, parent, reg, shift)->clk
97 #define imx_clk_mux(name, reg, shift, width, parents, num_parents) \
98 imx_clk_hw_mux(name, reg, shift, width, parents, num_parents)->clk
100 struct clk
*imx_clk_pll14xx(const char *name
, const char *parent_name
,
101 void __iomem
*base
, const struct imx_pll14xx_clk
*pll_clk
);
103 struct clk
*imx_clk_pllv1(enum imx_pllv1_type type
, const char *name
,
104 const char *parent
, void __iomem
*base
);
106 struct clk
*imx_clk_pllv2(const char *name
, const char *parent
,
109 struct clk
*imx_clk_frac_pll(const char *name
, const char *parent_name
,
112 struct clk
*imx_clk_sccg_pll(const char *name
,
113 const char * const *parent_names
,
115 u8 parent
, u8 bypass1
, u8 bypass2
,
117 unsigned long flags
);
119 enum imx_pllv3_type
{
132 struct 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
);
135 #define PLL_1416X_RATE(_rate, _m, _p, _s) \
143 #define PLL_1443X_RATE(_rate, _m, _p, _s, _k) \
152 struct clk_hw
*imx_clk_pllv4(const char *name
, const char *parent_name
,
155 struct 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
);
161 struct clk
* imx_obtain_fixed_clock(
162 const char *name
, unsigned long rate
);
164 struct clk_hw
*imx_obtain_fixed_clock_hw(
165 const char *name
, unsigned long rate
);
167 struct clk_hw
*imx_obtain_fixed_clk_hw(struct device_node
*np
,
170 struct clk_hw
*imx_clk_hw_gate_exclusive(const char *name
, const char *parent
,
171 void __iomem
*reg
, u8 shift
, u32 exclusive_mask
);
173 struct clk_hw
*imx_clk_hw_pfd(const char *name
, const char *parent_name
,
174 void __iomem
*reg
, u8 idx
);
176 struct clk_hw
*imx_clk_pfdv2(const char *name
, const char *parent_name
,
177 void __iomem
*reg
, u8 idx
);
179 struct 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
);
183 struct 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
);
187 struct 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
,
193 struct 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
));
197 struct 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
));
201 static inline struct clk
*imx_clk_fixed(const char *name
, int rate
)
203 return clk_register_fixed_rate(NULL
, name
, NULL
, 0, rate
);
206 static inline struct clk_hw
*imx_clk_hw_fixed(const char *name
, int rate
)
208 return clk_hw_register_fixed_rate(NULL
, name
, NULL
, 0, rate
);
211 static inline struct clk_hw
*imx_clk_hw_mux_ldb(const char *name
, void __iomem
*reg
,
212 u8 shift
, u8 width
, const char * const *parents
,
215 return clk_hw_register_mux(NULL
, name
, parents
, num_parents
,
216 CLK_SET_RATE_NO_REPARENT
| CLK_SET_RATE_PARENT
, reg
,
217 shift
, width
, CLK_MUX_READ_ONLY
, &imx_ccm_lock
);
220 static inline struct clk_hw
*imx_clk_hw_fixed_factor(const char *name
,
221 const char *parent
, unsigned int mult
, unsigned int div
)
223 return clk_hw_register_fixed_factor(NULL
, name
, parent
,
224 CLK_SET_RATE_PARENT
, mult
, div
);
227 static inline struct clk
*imx_clk_divider(const char *name
, const char *parent
,
228 void __iomem
*reg
, u8 shift
, u8 width
)
230 return clk_register_divider(NULL
, name
, parent
, CLK_SET_RATE_PARENT
,
231 reg
, shift
, width
, 0, &imx_ccm_lock
);
234 static inline struct clk_hw
*imx_clk_hw_divider(const char *name
,
236 void __iomem
*reg
, u8 shift
,
239 return clk_hw_register_divider(NULL
, name
, parent
, CLK_SET_RATE_PARENT
,
240 reg
, shift
, width
, 0, &imx_ccm_lock
);
243 static inline struct clk
*imx_clk_divider_flags(const char *name
,
244 const char *parent
, void __iomem
*reg
, u8 shift
, u8 width
,
247 return clk_register_divider(NULL
, name
, parent
, flags
,
248 reg
, shift
, width
, 0, &imx_ccm_lock
);
251 static inline struct clk_hw
*imx_clk_hw_divider_flags(const char *name
,
253 void __iomem
*reg
, u8 shift
,
254 u8 width
, unsigned long flags
)
256 return clk_hw_register_divider(NULL
, name
, parent
, flags
,
257 reg
, shift
, width
, 0, &imx_ccm_lock
);
260 static inline struct clk_hw
*imx_clk_hw_divider2(const char *name
, const char *parent
,
261 void __iomem
*reg
, u8 shift
, u8 width
)
263 return clk_hw_register_divider(NULL
, name
, parent
,
264 CLK_SET_RATE_PARENT
| CLK_OPS_PARENT_ENABLE
,
265 reg
, shift
, width
, 0, &imx_ccm_lock
);
268 static inline struct clk
*imx_clk_divider2_flags(const char *name
,
269 const char *parent
, void __iomem
*reg
, u8 shift
, u8 width
,
272 return clk_register_divider(NULL
, name
, parent
,
273 flags
| CLK_SET_RATE_PARENT
| CLK_OPS_PARENT_ENABLE
,
274 reg
, shift
, width
, 0, &imx_ccm_lock
);
277 static inline struct clk
*imx_clk_gate(const char *name
, const char *parent
,
278 void __iomem
*reg
, u8 shift
)
280 return clk_register_gate(NULL
, name
, parent
, CLK_SET_RATE_PARENT
, reg
,
281 shift
, 0, &imx_ccm_lock
);
284 static inline struct clk_hw
*imx_clk_hw_gate_flags(const char *name
, const char *parent
,
285 void __iomem
*reg
, u8 shift
, unsigned long flags
)
287 return clk_hw_register_gate(NULL
, name
, parent
, flags
| CLK_SET_RATE_PARENT
, reg
,
288 shift
, 0, &imx_ccm_lock
);
291 static inline struct clk_hw
*imx_clk_hw_gate(const char *name
, const char *parent
,
292 void __iomem
*reg
, u8 shift
)
294 return clk_hw_register_gate(NULL
, name
, parent
, CLK_SET_RATE_PARENT
, reg
,
295 shift
, 0, &imx_ccm_lock
);
298 static inline struct clk_hw
*imx_clk_hw_gate_dis(const char *name
, const char *parent
,
299 void __iomem
*reg
, u8 shift
)
301 return clk_hw_register_gate(NULL
, name
, parent
, CLK_SET_RATE_PARENT
, reg
,
302 shift
, CLK_GATE_SET_TO_DISABLE
, &imx_ccm_lock
);
305 static inline struct clk_hw
*imx_clk_hw_gate_dis_flags(const char *name
, const char *parent
,
306 void __iomem
*reg
, u8 shift
, unsigned long flags
)
308 return clk_hw_register_gate(NULL
, name
, parent
, flags
| CLK_SET_RATE_PARENT
, reg
,
309 shift
, CLK_GATE_SET_TO_DISABLE
, &imx_ccm_lock
);
312 static inline struct clk_hw
*imx_clk_hw_gate2(const char *name
, const char *parent
,
313 void __iomem
*reg
, u8 shift
)
315 return clk_hw_register_gate2(NULL
, name
, parent
, CLK_SET_RATE_PARENT
, reg
,
316 shift
, 0x3, 0, &imx_ccm_lock
, NULL
);
319 static inline struct clk_hw
*imx_clk_hw_gate2_flags(const char *name
, const char *parent
,
320 void __iomem
*reg
, u8 shift
, unsigned long flags
)
322 return clk_hw_register_gate2(NULL
, name
, parent
, flags
| CLK_SET_RATE_PARENT
, reg
,
323 shift
, 0x3, 0, &imx_ccm_lock
, NULL
);
326 static inline struct clk_hw
*imx_clk_hw_gate2_shared(const char *name
,
327 const char *parent
, void __iomem
*reg
, u8 shift
,
328 unsigned int *share_count
)
330 return clk_hw_register_gate2(NULL
, name
, parent
, CLK_SET_RATE_PARENT
, reg
,
331 shift
, 0x3, 0, &imx_ccm_lock
, share_count
);
334 static inline struct clk_hw
*imx_clk_hw_gate2_shared2(const char *name
,
335 const char *parent
, void __iomem
*reg
, u8 shift
,
336 unsigned int *share_count
)
338 return clk_hw_register_gate2(NULL
, name
, parent
, CLK_SET_RATE_PARENT
|
339 CLK_OPS_PARENT_ENABLE
, reg
, shift
, 0x3, 0,
340 &imx_ccm_lock
, share_count
);
343 static inline struct clk
*imx_clk_gate2_cgr(const char *name
,
344 const char *parent
, void __iomem
*reg
, u8 shift
, u8 cgr_val
)
346 return clk_register_gate2(NULL
, name
, parent
, CLK_SET_RATE_PARENT
, reg
,
347 shift
, cgr_val
, 0, &imx_ccm_lock
, NULL
);
350 static inline struct clk_hw
*imx_clk_hw_gate3(const char *name
, const char *parent
,
351 void __iomem
*reg
, u8 shift
)
353 return clk_hw_register_gate(NULL
, name
, parent
,
354 CLK_SET_RATE_PARENT
| CLK_OPS_PARENT_ENABLE
,
355 reg
, shift
, 0, &imx_ccm_lock
);
358 static inline struct clk
*imx_clk_gate3_flags(const char *name
,
359 const char *parent
, void __iomem
*reg
, u8 shift
,
362 return clk_register_gate(NULL
, name
, parent
,
363 flags
| CLK_SET_RATE_PARENT
| CLK_OPS_PARENT_ENABLE
,
364 reg
, shift
, 0, &imx_ccm_lock
);
367 static inline struct clk_hw
*imx_clk_hw_gate4(const char *name
, const char *parent
,
368 void __iomem
*reg
, u8 shift
)
370 return clk_hw_register_gate2(NULL
, name
, parent
,
371 CLK_SET_RATE_PARENT
| CLK_OPS_PARENT_ENABLE
,
372 reg
, shift
, 0x3, 0, &imx_ccm_lock
, NULL
);
375 static inline struct clk
*imx_clk_gate4_flags(const char *name
,
376 const char *parent
, void __iomem
*reg
, u8 shift
,
379 return clk_register_gate2(NULL
, name
, parent
,
380 flags
| CLK_SET_RATE_PARENT
| CLK_OPS_PARENT_ENABLE
,
381 reg
, shift
, 0x3, 0, &imx_ccm_lock
, NULL
);
384 static inline struct clk_hw
*imx_clk_hw_mux(const char *name
, void __iomem
*reg
,
385 u8 shift
, u8 width
, const char * const *parents
,
388 return clk_hw_register_mux(NULL
, name
, parents
, num_parents
,
389 CLK_SET_RATE_NO_REPARENT
, reg
, shift
,
390 width
, 0, &imx_ccm_lock
);
393 static inline struct clk
*imx_clk_mux2(const char *name
, void __iomem
*reg
,
394 u8 shift
, u8 width
, const char * const *parents
,
397 return clk_register_mux(NULL
, name
, parents
, num_parents
,
398 CLK_SET_RATE_NO_REPARENT
| CLK_OPS_PARENT_ENABLE
,
399 reg
, shift
, width
, 0, &imx_ccm_lock
);
402 static inline struct clk_hw
*imx_clk_hw_mux2(const char *name
, void __iomem
*reg
,
404 const char * const *parents
,
407 return clk_hw_register_mux(NULL
, name
, parents
, num_parents
,
408 CLK_SET_RATE_NO_REPARENT
|
409 CLK_OPS_PARENT_ENABLE
,
410 reg
, shift
, width
, 0, &imx_ccm_lock
);
413 static inline struct clk
*imx_clk_mux_flags(const char *name
,
414 void __iomem
*reg
, u8 shift
, u8 width
,
415 const char * const *parents
, int num_parents
,
418 return clk_register_mux(NULL
, name
, parents
, num_parents
,
419 flags
| CLK_SET_RATE_NO_REPARENT
, reg
, shift
, width
, 0,
423 static inline struct clk
*imx_clk_mux2_flags(const char *name
,
424 void __iomem
*reg
, u8 shift
, u8 width
,
425 const char * const *parents
,
426 int num_parents
, unsigned long flags
)
428 return clk_register_mux(NULL
, name
, parents
, num_parents
,
429 flags
| CLK_SET_RATE_NO_REPARENT
| CLK_OPS_PARENT_ENABLE
,
430 reg
, shift
, width
, 0, &imx_ccm_lock
);
433 static inline struct clk_hw
*imx_clk_hw_mux_flags(const char *name
,
434 void __iomem
*reg
, u8 shift
,
436 const char * const *parents
,
440 return clk_hw_register_mux(NULL
, name
, parents
, num_parents
,
441 flags
| CLK_SET_RATE_NO_REPARENT
,
442 reg
, shift
, width
, 0, &imx_ccm_lock
);
445 struct clk_hw
*imx_clk_hw_cpu(const char *name
, const char *parent_name
,
446 struct clk
*div
, struct clk
*mux
, struct clk
*pll
,
449 struct clk
*imx8m_clk_composite_flags(const char *name
,
450 const char * const *parent_names
,
451 int num_parents
, void __iomem
*reg
,
452 unsigned long flags
);
454 #define __imx8m_clk_composite(name, parent_names, reg, flags) \
455 imx8m_clk_composite_flags(name, parent_names, \
456 ARRAY_SIZE(parent_names), reg, \
457 flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
459 #define imx8m_clk_composite(name, parent_names, reg) \
460 __imx8m_clk_composite(name, parent_names, reg, 0)
462 #define imx8m_clk_composite_critical(name, parent_names, reg) \
463 __imx8m_clk_composite(name, parent_names, reg, CLK_IS_CRITICAL)
465 struct clk_hw
*imx_clk_divider_gate(const char *name
, const char *parent_name
,
466 unsigned long flags
, void __iomem
*reg
, u8 shift
, u8 width
,
467 u8 clk_divider_flags
, const struct clk_div_table
*table
,