xref: /openbmc/linux/drivers/clk/imx/clk.h (revision dc6a81c3)
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 
8 extern spinlock_t imx_ccm_lock;
9 
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);
16 
17 extern void imx_cscmr1_fixup(u32 *val);
18 
19 enum 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 
28 enum imx_sscg_pll_type {
29 	SCCG_PLL1,
30 	SCCG_PLL2,
31 };
32 
33 enum imx_pll14xx_type {
34 	PLL_1416X,
35 	PLL_1443X,
36 };
37 
38 /* NOTE: Rate table should be kept sorted in descending order. */
39 struct 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 
47 struct 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 
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;
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 
128 struct 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 
134 struct 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 
138 struct clk_hw *imx_clk_hw_pllv1(enum imx_pllv1_type type, const char *name,
139 		const char *parent, void __iomem *base);
140 
141 struct clk_hw *imx_clk_hw_pllv2(const char *name, const char *parent,
142 		void __iomem *base);
143 
144 struct clk_hw *imx_clk_hw_frac_pll(const char *name, const char *parent_name,
145 			     void __iomem *base);
146 
147 struct 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 
154 enum 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 
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);
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 
187 struct clk_hw *imx_clk_hw_pllv4(const char *name, const char *parent_name,
188 			     void __iomem *base);
189 
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);
195 
196 struct clk * imx_obtain_fixed_clock(
197 			const char *name, unsigned long rate);
198 
199 struct clk_hw *imx_obtain_fixed_clock_hw(
200 			const char *name, unsigned long rate);
201 
202 struct clk_hw *imx_obtain_fixed_clk_hw(struct device_node *np,
203 				       const char *name);
204 
205 struct clk_hw *imx_clk_hw_gate_exclusive(const char *name, const char *parent,
206 	 void __iomem *reg, u8 shift, u32 exclusive_mask);
207 
208 struct clk_hw *imx_clk_hw_pfd(const char *name, const char *parent_name,
209 		void __iomem *reg, u8 idx);
210 
211 struct clk_hw *imx_clk_hw_pfdv2(const char *name, const char *parent_name,
212 			     void __iomem *reg, u8 idx);
213 
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);
217 
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);
221 
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,
226 				     void __iomem *reg);
227 
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));
231 
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));
235 
236 static 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 
243 static 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 
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,
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 
257 static 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 
264 static 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 
273 static 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 
282 static 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 
290 static 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 
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)
301 {
302 	return clk_hw_register_gate(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg,
303 			shift, 0, &imx_ccm_lock);
304 }
305 
306 static 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 
313 static 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 
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)
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 
327 static 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 
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)
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 
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)
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 
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)
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 
358 static 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 
365 static 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 
373 static 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 
385 static 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 
393 static 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 
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,
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 
414 static 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 
423 static 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 
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,
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 
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)
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 
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)
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 
464 static 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 
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,
478 		struct clk *step);
479 
480 struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
481 					    const char * const *parent_names,
482 					    int num_parents,
483 					    void __iomem *reg,
484 					    unsigned long flags);
485 
486 #define imx8m_clk_composite_flags(name, parent_names, num_parents, reg, \
487 				  flags) \
488 	to_clk(imx8m_clk_hw_composite_flags(name, parent_names, \
489 				num_parents, reg, flags))
490 
491 #define __imx8m_clk_hw_composite(name, parent_names, reg, flags) \
492 	imx8m_clk_hw_composite_flags(name, parent_names, \
493 		ARRAY_SIZE(parent_names), reg, \
494 		flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
495 
496 #define __imx8m_clk_composite(name, parent_names, reg, flags) \
497 	to_clk(__imx8m_clk_hw_composite(name, parent_names, reg, flags))
498 
499 #define imx8m_clk_hw_composite(name, parent_names, reg) \
500 	__imx8m_clk_hw_composite(name, parent_names, reg, 0)
501 
502 #define imx8m_clk_composite(name, parent_names, reg) \
503 	__imx8m_clk_composite(name, parent_names, reg, 0)
504 
505 #define imx8m_clk_hw_composite_critical(name, parent_names, reg) \
506 	__imx8m_clk_hw_composite(name, parent_names, reg, CLK_IS_CRITICAL)
507 
508 #define imx8m_clk_composite_critical(name, parent_names, reg) \
509 	__imx8m_clk_composite(name, parent_names, reg, CLK_IS_CRITICAL)
510 
511 struct clk_hw *imx_clk_hw_divider_gate(const char *name, const char *parent_name,
512 		unsigned long flags, void __iomem *reg, u8 shift, u8 width,
513 		u8 clk_divider_flags, const struct clk_div_table *table,
514 		spinlock_t *lock);
515 #endif
516