1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef __MACH_IMX_CLK_H
3 #define __MACH_IMX_CLK_H
5 #include <linux/bits.h>
6 #include <linux/spinlock.h>
7 #include <linux/clk-provider.h>
9 extern spinlock_t imx_ccm_lock
;
10 extern bool mcore_booted
;
12 void imx_check_clocks(struct clk
*clks
[], unsigned int count
);
13 void imx_check_clk_hws(struct clk_hw
*clks
[], unsigned int count
);
15 void imx_register_uart_clocks(void);
17 static inline void imx_register_uart_clocks(void)
21 void imx_mmdc_mask_handshake(void __iomem
*ccm_base
, unsigned int chn
);
22 void imx_unregister_hw_clocks(struct clk_hw
*hws
[], unsigned int count
);
24 extern void imx_cscmr1_fixup(u32
*val
);
35 enum imx_sscg_pll_type
{
40 enum imx_pll14xx_type
{
48 IMX_PLLV4_IMX8ULP_1GHZ
,
56 /* NOTE: Rate table should be kept sorted in descending order. */
57 struct imx_pll14xx_rate_table
{
65 struct imx_pll14xx_clk
{
66 enum imx_pll14xx_type type
;
67 const struct imx_pll14xx_rate_table
*rate_table
;
72 extern struct imx_pll14xx_clk imx_1416x_pll
;
73 extern struct imx_pll14xx_clk imx_1443x_pll
;
74 extern struct imx_pll14xx_clk imx_1443x_dram_pll
;
76 #define CLK_FRACN_GPPLL_INTEGER BIT(0)
77 #define CLK_FRACN_GPPLL_FRACN BIT(1)
79 /* NOTE: Rate table should be kept sorted in descending order. */
80 struct imx_fracn_gppll_rate_table
{
89 struct imx_fracn_gppll_clk
{
90 const struct imx_fracn_gppll_rate_table
*rate_table
;
95 struct clk_hw
*imx_clk_fracn_gppll(const char *name
, const char *parent_name
, void __iomem
*base
,
96 const struct imx_fracn_gppll_clk
*pll_clk
);
97 struct clk_hw
*imx_clk_fracn_gppll_integer(const char *name
, const char *parent_name
,
99 const struct imx_fracn_gppll_clk
*pll_clk
);
101 extern struct imx_fracn_gppll_clk imx_fracn_gppll
;
102 extern struct imx_fracn_gppll_clk imx_fracn_gppll_integer
;
104 #define imx_clk_cpu(name, parent_name, div, mux, pll, step) \
105 to_clk(imx_clk_hw_cpu(name, parent_name, div, mux, pll, step))
107 #define clk_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \
108 cgr_val, cgr_mask, clk_gate_flags, lock, share_count) \
109 to_clk(clk_hw_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \
110 cgr_val, cgr_mask, clk_gate_flags, lock, share_count))
112 #define imx_clk_pllv3(type, name, parent_name, base, div_mask) \
113 to_clk(imx_clk_hw_pllv3(type, name, parent_name, base, div_mask))
115 #define imx_clk_pfd(name, parent_name, reg, idx) \
116 to_clk(imx_clk_hw_pfd(name, parent_name, reg, idx))
118 #define imx_clk_gate_exclusive(name, parent, reg, shift, exclusive_mask) \
119 to_clk(imx_clk_hw_gate_exclusive(name, parent, reg, shift, exclusive_mask))
121 #define imx_clk_fixed(name, rate) \
122 to_clk(imx_clk_hw_fixed(name, rate))
124 #define imx_clk_fixed_factor(name, parent, mult, div) \
125 to_clk(imx_clk_hw_fixed_factor(name, parent, mult, div))
127 #define imx_clk_divider(name, parent, reg, shift, width) \
128 to_clk(imx_clk_hw_divider(name, parent, reg, shift, width))
130 #define imx_clk_divider_flags(name, parent, reg, shift, width, flags) \
131 to_clk(imx_clk_hw_divider_flags(name, parent, reg, shift, width, flags))
133 #define imx_clk_gate(name, parent, reg, shift) \
134 to_clk(imx_clk_hw_gate(name, parent, reg, shift))
136 #define imx_clk_gate_dis(name, parent, reg, shift) \
137 to_clk(imx_clk_hw_gate_dis(name, parent, reg, shift))
139 #define imx_clk_gate2(name, parent, reg, shift) \
140 to_clk(imx_clk_hw_gate2(name, parent, reg, shift))
142 #define imx_clk_gate2_cgr(name, parent, reg, shift, cgr_val) \
143 to_clk(__imx_clk_hw_gate2(name, parent, reg, shift, cgr_val, 0, NULL))
145 #define imx_clk_gate2_flags(name, parent, reg, shift, flags) \
146 to_clk(imx_clk_hw_gate2_flags(name, parent, reg, shift, flags))
148 #define imx_clk_mux(name, reg, shift, width, parents, num_parents) \
149 to_clk(imx_clk_hw_mux(name, reg, shift, width, parents, num_parents))
151 #define imx_clk_mux_flags(name, reg, shift, width, parents, num_parents, flags) \
152 to_clk(imx_clk_hw_mux_flags(name, reg, shift, width, parents, num_parents, flags))
154 #define imx_clk_mux2_flags(name, reg, shift, width, parents, num_parents, flags) \
155 to_clk(imx_clk_hw_mux2_flags(name, reg, shift, width, parents, num_parents, flags))
157 #define imx_clk_pllv1(type, name, parent, base) \
158 to_clk(imx_clk_hw_pllv1(type, name, parent, base))
160 #define imx_clk_pllv2(name, parent, base) \
161 to_clk(imx_clk_hw_pllv2(name, parent, base))
163 #define imx_clk_hw_gate(name, parent, reg, shift) \
164 imx_clk_hw_gate_flags(name, parent, reg, shift, 0)
166 #define imx_clk_hw_gate2(name, parent, reg, shift) \
167 imx_clk_hw_gate2_flags(name, parent, reg, shift, 0)
169 #define imx_clk_hw_gate_dis(name, parent, reg, shift) \
170 imx_clk_hw_gate_dis_flags(name, parent, reg, shift, 0)
172 #define imx_clk_hw_gate_dis_flags(name, parent, reg, shift, flags) \
173 __imx_clk_hw_gate(name, parent, reg, shift, flags, CLK_GATE_SET_TO_DISABLE)
175 #define imx_clk_hw_gate_flags(name, parent, reg, shift, flags) \
176 __imx_clk_hw_gate(name, parent, reg, shift, flags, 0)
178 #define imx_clk_hw_gate2_flags(name, parent, reg, shift, flags) \
179 __imx_clk_hw_gate2(name, parent, reg, shift, 0x3, flags, NULL)
181 #define imx_clk_hw_gate2_shared(name, parent, reg, shift, shared_count) \
182 __imx_clk_hw_gate2(name, parent, reg, shift, 0x3, 0, shared_count)
184 #define imx_clk_hw_gate2_shared2(name, parent, reg, shift, shared_count) \
185 __imx_clk_hw_gate2(name, parent, reg, shift, 0x3, CLK_OPS_PARENT_ENABLE, shared_count)
187 #define imx_clk_hw_gate3(name, parent, reg, shift) \
188 imx_clk_hw_gate3_flags(name, parent, reg, shift, 0)
190 #define imx_clk_hw_gate3_flags(name, parent, reg, shift, flags) \
191 __imx_clk_hw_gate(name, parent, reg, shift, flags | CLK_OPS_PARENT_ENABLE, 0)
193 #define imx_clk_hw_gate4(name, parent, reg, shift) \
194 imx_clk_hw_gate4_flags(name, parent, reg, shift, 0)
196 #define imx_clk_hw_gate4_flags(name, parent, reg, shift, flags) \
197 imx_clk_hw_gate2_flags(name, parent, reg, shift, flags | CLK_OPS_PARENT_ENABLE)
199 #define imx_clk_hw_mux2(name, reg, shift, width, parents, num_parents) \
200 imx_clk_hw_mux2_flags(name, reg, shift, width, parents, num_parents, 0)
202 #define imx_clk_hw_mux(name, reg, shift, width, parents, num_parents) \
203 __imx_clk_hw_mux(name, reg, shift, width, parents, num_parents, 0, 0)
205 #define imx_clk_hw_mux_flags(name, reg, shift, width, parents, num_parents, flags) \
206 __imx_clk_hw_mux(name, reg, shift, width, parents, num_parents, flags, 0)
208 #define imx_clk_hw_mux_ldb(name, reg, shift, width, parents, num_parents) \
209 __imx_clk_hw_mux(name, reg, shift, width, parents, num_parents, CLK_SET_RATE_PARENT, CLK_MUX_READ_ONLY)
211 #define imx_clk_hw_mux2_flags(name, reg, shift, width, parents, num_parents, flags) \
212 __imx_clk_hw_mux(name, reg, shift, width, parents, num_parents, flags | CLK_OPS_PARENT_ENABLE, 0)
214 #define imx_clk_hw_divider(name, parent, reg, shift, width) \
215 __imx_clk_hw_divider(name, parent, reg, shift, width, CLK_SET_RATE_PARENT)
217 #define imx_clk_hw_divider2(name, parent, reg, shift, width) \
218 __imx_clk_hw_divider(name, parent, reg, shift, width, \
219 CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE)
221 #define imx_clk_hw_divider_flags(name, parent, reg, shift, width, flags) \
222 __imx_clk_hw_divider(name, parent, reg, shift, width, flags)
224 #define imx_clk_hw_pll14xx(name, parent_name, base, pll_clk) \
225 imx_dev_clk_hw_pll14xx(NULL, name, parent_name, base, pll_clk)
227 struct clk_hw
*imx_dev_clk_hw_pll14xx(struct device
*dev
, const char *name
,
228 const char *parent_name
, void __iomem
*base
,
229 const struct imx_pll14xx_clk
*pll_clk
);
231 struct clk_hw
*imx_clk_hw_pllv1(enum imx_pllv1_type type
, const char *name
,
232 const char *parent
, void __iomem
*base
);
234 struct clk_hw
*imx_clk_hw_pllv2(const char *name
, const char *parent
,
237 struct clk_hw
*imx_clk_hw_frac_pll(const char *name
, const char *parent_name
,
240 struct clk_hw
*imx_clk_hw_sscg_pll(const char *name
,
241 const char * const *parent_names
,
243 u8 parent
, u8 bypass1
, u8 bypass2
,
245 unsigned long flags
);
247 enum imx_pllv3_type
{
260 struct clk_hw
*imx_clk_hw_pllv3(enum imx_pllv3_type type
, const char *name
,
261 const char *parent_name
, void __iomem
*base
, u32 div_mask
);
263 #define PLL_1416X_RATE(_rate, _m, _p, _s) \
271 #define PLL_1443X_RATE(_rate, _m, _p, _s, _k) \
280 struct clk_hw
*imx_clk_hw_pllv4(enum imx_pllv4_type type
, const char *name
,
281 const char *parent_name
, void __iomem
*base
);
283 struct clk_hw
*clk_hw_register_gate2(struct device
*dev
, const char *name
,
284 const char *parent_name
, unsigned long flags
,
285 void __iomem
*reg
, u8 bit_idx
, u8 cgr_val
, u8 cgr_mask
,
286 u8 clk_gate_flags
, spinlock_t
*lock
,
287 unsigned int *share_count
);
289 struct clk
* imx_obtain_fixed_clock(
290 const char *name
, unsigned long rate
);
292 struct clk_hw
*imx_obtain_fixed_clock_hw(
293 const char *name
, unsigned long rate
);
295 struct clk_hw
*imx_obtain_fixed_of_clock(struct device_node
*np
,
296 const char *name
, unsigned long rate
);
298 struct clk_hw
*imx_get_clk_hw_by_name(struct device_node
*np
, const char *name
);
300 struct clk_hw
*imx_clk_hw_gate_exclusive(const char *name
, const char *parent
,
301 void __iomem
*reg
, u8 shift
, u32 exclusive_mask
);
303 struct clk_hw
*imx_clk_hw_pfd(const char *name
, const char *parent_name
,
304 void __iomem
*reg
, u8 idx
);
306 struct clk_hw
*imx_clk_hw_pfdv2(enum imx_pfdv2_type type
, const char *name
,
307 const char *parent_name
, void __iomem
*reg
, u8 idx
);
309 struct clk_hw
*imx_clk_hw_busy_divider(const char *name
, const char *parent_name
,
310 void __iomem
*reg
, u8 shift
, u8 width
,
311 void __iomem
*busy_reg
, u8 busy_shift
);
313 struct clk_hw
*imx_clk_hw_busy_mux(const char *name
, void __iomem
*reg
, u8 shift
,
314 u8 width
, void __iomem
*busy_reg
, u8 busy_shift
,
315 const char * const *parent_names
, int num_parents
);
317 struct clk_hw
*imx7ulp_clk_hw_composite(const char *name
,
318 const char * const *parent_names
,
319 int num_parents
, bool mux_present
,
320 bool rate_present
, bool gate_present
,
323 struct clk_hw
*imx8ulp_clk_hw_composite(const char *name
,
324 const char * const *parent_names
,
325 int num_parents
, bool mux_present
,
326 bool rate_present
, bool gate_present
,
327 void __iomem
*reg
, bool has_swrst
);
329 struct clk_hw
*imx_clk_hw_fixup_divider(const char *name
, const char *parent
,
330 void __iomem
*reg
, u8 shift
, u8 width
,
331 void (*fixup
)(u32
*val
));
333 struct clk_hw
*imx_clk_hw_fixup_mux(const char *name
, void __iomem
*reg
,
334 u8 shift
, u8 width
, const char * const *parents
,
335 int num_parents
, void (*fixup
)(u32
*val
));
337 static inline struct clk
*to_clk(struct clk_hw
*hw
)
339 if (IS_ERR_OR_NULL(hw
))
344 static inline struct clk_hw
*imx_clk_hw_fixed(const char *name
, int rate
)
346 return clk_hw_register_fixed_rate(NULL
, name
, NULL
, 0, rate
);
349 static inline struct clk_hw
*imx_clk_hw_fixed_factor(const char *name
,
350 const char *parent
, unsigned int mult
, unsigned int div
)
352 return clk_hw_register_fixed_factor(NULL
, name
, parent
,
353 CLK_SET_RATE_PARENT
, mult
, div
);
356 static inline struct clk_hw
*imx_clk_hw_divider_closest(const char *name
,
358 void __iomem
*reg
, u8 shift
,
361 return clk_hw_register_divider(NULL
, name
, parent
, 0,
362 reg
, shift
, width
, CLK_DIVIDER_ROUND_CLOSEST
, &imx_ccm_lock
);
365 static inline struct clk_hw
*__imx_clk_hw_divider(const char *name
,
367 void __iomem
*reg
, u8 shift
,
368 u8 width
, unsigned long flags
)
370 return clk_hw_register_divider(NULL
, name
, parent
, flags
,
371 reg
, shift
, width
, 0, &imx_ccm_lock
);
374 static inline struct clk_hw
*__imx_clk_hw_gate(const char *name
, const char *parent
,
375 void __iomem
*reg
, u8 shift
,
377 unsigned long clk_gate_flags
)
379 return clk_hw_register_gate(NULL
, name
, parent
, flags
| CLK_SET_RATE_PARENT
, reg
,
380 shift
, clk_gate_flags
, &imx_ccm_lock
);
383 static inline struct clk_hw
*__imx_clk_hw_gate2(const char *name
, const char *parent
,
384 void __iomem
*reg
, u8 shift
, u8 cgr_val
,
386 unsigned int *share_count
)
388 return clk_hw_register_gate2(NULL
, name
, parent
, flags
| CLK_SET_RATE_PARENT
, reg
,
389 shift
, cgr_val
, 0x3, 0, &imx_ccm_lock
, share_count
);
392 static inline struct clk_hw
*__imx_clk_hw_mux(const char *name
, void __iomem
*reg
,
393 u8 shift
, u8 width
, const char * const *parents
,
394 int num_parents
, unsigned long flags
, unsigned long clk_mux_flags
)
396 return clk_hw_register_mux(NULL
, name
, parents
, num_parents
,
397 flags
| CLK_SET_RATE_NO_REPARENT
, reg
, shift
,
398 width
, clk_mux_flags
, &imx_ccm_lock
);
401 struct clk_hw
*imx_clk_hw_cpu(const char *name
, const char *parent_name
,
402 struct clk
*div
, struct clk
*mux
, struct clk
*pll
,
405 #define IMX_COMPOSITE_CORE BIT(0)
406 #define IMX_COMPOSITE_BUS BIT(1)
407 #define IMX_COMPOSITE_FW_MANAGED BIT(2)
409 #define IMX_COMPOSITE_CLK_FLAGS_DEFAULT \
410 (CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
411 #define IMX_COMPOSITE_CLK_FLAGS_CRITICAL \
412 (IMX_COMPOSITE_CLK_FLAGS_DEFAULT | CLK_IS_CRITICAL)
413 #define IMX_COMPOSITE_CLK_FLAGS_GET_RATE_NO_CACHE \
414 (IMX_COMPOSITE_CLK_FLAGS_DEFAULT | CLK_GET_RATE_NOCACHE)
415 #define IMX_COMPOSITE_CLK_FLAGS_CRITICAL_GET_RATE_NO_CACHE \
416 (IMX_COMPOSITE_CLK_FLAGS_GET_RATE_NO_CACHE | CLK_IS_CRITICAL)
418 struct clk_hw
*__imx8m_clk_hw_composite(const char *name
,
419 const char * const *parent_names
,
423 unsigned long flags
);
425 #define _imx8m_clk_hw_composite(name, parent_names, reg, composite_flags, flags) \
426 __imx8m_clk_hw_composite(name, parent_names, \
427 ARRAY_SIZE(parent_names), reg, composite_flags, flags)
429 #define imx8m_clk_hw_composite(name, parent_names, reg) \
430 _imx8m_clk_hw_composite(name, parent_names, reg, \
431 0, IMX_COMPOSITE_CLK_FLAGS_DEFAULT)
433 #define imx8m_clk_hw_composite_flags(name, parent_names, reg, flags) \
434 _imx8m_clk_hw_composite(name, parent_names, reg, \
435 0, IMX_COMPOSITE_CLK_FLAGS_DEFAULT | flags)
437 #define imx8m_clk_hw_composite_critical(name, parent_names, reg) \
438 _imx8m_clk_hw_composite(name, parent_names, reg, \
439 0, IMX_COMPOSITE_CLK_FLAGS_CRITICAL)
441 #define imx8m_clk_hw_composite_bus(name, parent_names, reg) \
442 _imx8m_clk_hw_composite(name, parent_names, reg, \
443 IMX_COMPOSITE_BUS, IMX_COMPOSITE_CLK_FLAGS_DEFAULT)
445 #define imx8m_clk_hw_composite_bus_flags(name, parent_names, reg, flags) \
446 _imx8m_clk_hw_composite(name, parent_names, reg, \
447 IMX_COMPOSITE_BUS, IMX_COMPOSITE_CLK_FLAGS_DEFAULT | flags)
449 #define imx8m_clk_hw_composite_bus_critical(name, parent_names, reg) \
450 _imx8m_clk_hw_composite(name, parent_names, reg, \
451 IMX_COMPOSITE_BUS, IMX_COMPOSITE_CLK_FLAGS_CRITICAL)
453 #define imx8m_clk_hw_composite_core(name, parent_names, reg) \
454 _imx8m_clk_hw_composite(name, parent_names, reg, \
455 IMX_COMPOSITE_CORE, IMX_COMPOSITE_CLK_FLAGS_DEFAULT)
457 #define imx8m_clk_hw_fw_managed_composite(name, parent_names, reg) \
458 _imx8m_clk_hw_composite(name, parent_names, reg, \
459 IMX_COMPOSITE_FW_MANAGED, \
460 IMX_COMPOSITE_CLK_FLAGS_GET_RATE_NO_CACHE)
462 #define imx8m_clk_hw_fw_managed_composite_critical(name, parent_names, reg) \
463 _imx8m_clk_hw_composite(name, parent_names, reg, \
464 IMX_COMPOSITE_FW_MANAGED, \
465 IMX_COMPOSITE_CLK_FLAGS_CRITICAL_GET_RATE_NO_CACHE)
467 struct clk_hw
*imx93_clk_composite_flags(const char *name
,
468 const char * const *parent_names
,
472 unsigned long flags
);
473 #define imx93_clk_composite(name, parent_names, num_parents, reg, domain_id) \
474 imx93_clk_composite_flags(name, parent_names, num_parents, reg, domain_id \
475 CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
477 struct clk_hw
*imx93_clk_gate(struct device
*dev
, const char *name
, const char *parent_name
,
478 unsigned long flags
, void __iomem
*reg
, u32 bit_idx
, u32 val
,
479 u32 mask
, u32 domain_id
, unsigned int *share_count
);
481 struct clk_hw
*imx_clk_hw_divider_gate(const char *name
, const char *parent_name
,
482 unsigned long flags
, void __iomem
*reg
, u8 shift
, u8 width
,
483 u8 clk_divider_flags
, const struct clk_div_table
*table
,
486 struct clk_hw
*imx_clk_gpr_mux(const char *name
, const char *compatible
,
487 u32 reg
, const char **parent_names
,
488 u8 num_parents
, const u32
*mux_table
, u32 mask
);