xref: /linux/drivers/clk/imx/clk.h (revision 8646d4dcc7fb2e6e771f8cee500950f3f69aa1ea)
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 
14 extern void imx_cscmr1_fixup(u32 *val);
15 
16 enum imx_pllv1_type {
17 	IMX_PLLV1_IMX1,
18 	IMX_PLLV1_IMX21,
19 	IMX_PLLV1_IMX25,
20 	IMX_PLLV1_IMX27,
21 	IMX_PLLV1_IMX31,
22 	IMX_PLLV1_IMX35,
23 };
24 
25 enum imx_sccg_pll_type {
26 	SCCG_PLL1,
27 	SCCG_PLL2,
28 };
29 
30 enum imx_pll14xx_type {
31 	PLL_1416X,
32 	PLL_1443X,
33 };
34 
35 /* NOTE: Rate table should be kept sorted in descending order. */
36 struct imx_pll14xx_rate_table {
37 	unsigned int rate;
38 	unsigned int pdiv;
39 	unsigned int mdiv;
40 	unsigned int sdiv;
41 	unsigned int kdiv;
42 };
43 
44 struct imx_pll14xx_clk {
45 	enum imx_pll14xx_type type;
46 	const struct imx_pll14xx_rate_table *rate_table;
47 	int rate_count;
48 	int flags;
49 };
50 
51 struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
52 		 void __iomem *base, const struct imx_pll14xx_clk *pll_clk);
53 
54 struct clk *imx_clk_pllv1(enum imx_pllv1_type type, const char *name,
55 		const char *parent, void __iomem *base);
56 
57 struct clk *imx_clk_pllv2(const char *name, const char *parent,
58 		void __iomem *base);
59 
60 struct clk *imx_clk_frac_pll(const char *name, const char *parent_name,
61 			     void __iomem *base);
62 
63 struct clk *imx_clk_sccg_pll(const char *name, const char *parent_name,
64 			     void __iomem *base,
65 			     enum imx_sccg_pll_type pll_type);
66 
67 enum imx_pllv3_type {
68 	IMX_PLLV3_GENERIC,
69 	IMX_PLLV3_SYS,
70 	IMX_PLLV3_USB,
71 	IMX_PLLV3_USB_VF610,
72 	IMX_PLLV3_AV,
73 	IMX_PLLV3_ENET,
74 	IMX_PLLV3_ENET_IMX7,
75 	IMX_PLLV3_SYS_VF610,
76 	IMX_PLLV3_DDR_IMX7,
77 };
78 
79 struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
80 		const char *parent_name, void __iomem *base, u32 div_mask);
81 
82 struct clk_hw *imx_clk_pllv4(const char *name, const char *parent_name,
83 			     void __iomem *base);
84 
85 struct clk *clk_register_gate2(struct device *dev, const char *name,
86 		const char *parent_name, unsigned long flags,
87 		void __iomem *reg, u8 bit_idx, u8 cgr_val,
88 		u8 clk_gate_flags, spinlock_t *lock,
89 		unsigned int *share_count);
90 
91 struct clk * imx_obtain_fixed_clock(
92 			const char *name, unsigned long rate);
93 
94 struct clk_hw *imx_obtain_fixed_clk_hw(struct device_node *np,
95 				       const char *name);
96 
97 struct clk *imx_clk_gate_exclusive(const char *name, const char *parent,
98 	 void __iomem *reg, u8 shift, u32 exclusive_mask);
99 
100 struct clk *imx_clk_pfd(const char *name, const char *parent_name,
101 		void __iomem *reg, u8 idx);
102 
103 struct clk_hw *imx_clk_pfdv2(const char *name, const char *parent_name,
104 			     void __iomem *reg, u8 idx);
105 
106 struct clk *imx_clk_busy_divider(const char *name, const char *parent_name,
107 				 void __iomem *reg, u8 shift, u8 width,
108 				 void __iomem *busy_reg, u8 busy_shift);
109 
110 struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift,
111 			     u8 width, void __iomem *busy_reg, u8 busy_shift,
112 			     const char * const *parent_names, int num_parents);
113 
114 struct clk_hw *imx7ulp_clk_composite(const char *name,
115 				     const char * const *parent_names,
116 				     int num_parents, bool mux_present,
117 				     bool rate_present, bool gate_present,
118 				     void __iomem *reg);
119 
120 struct clk *imx_clk_fixup_divider(const char *name, const char *parent,
121 				  void __iomem *reg, u8 shift, u8 width,
122 				  void (*fixup)(u32 *val));
123 
124 struct clk *imx_clk_fixup_mux(const char *name, void __iomem *reg,
125 			      u8 shift, u8 width, const char * const *parents,
126 			      int num_parents, void (*fixup)(u32 *val));
127 
128 static inline struct clk *imx_clk_fixed(const char *name, int rate)
129 {
130 	return clk_register_fixed_rate(NULL, name, NULL, 0, rate);
131 }
132 
133 static inline struct clk_hw *imx_clk_hw_fixed(const char *name, int rate)
134 {
135 	return clk_hw_register_fixed_rate(NULL, name, NULL, 0, rate);
136 }
137 
138 static inline struct clk_hw *imx_get_clk_hw_fixed(const char *name, int rate)
139 {
140 	return clk_hw_register_fixed_rate(NULL, name, NULL, 0, rate);
141 }
142 
143 static inline struct clk *imx_clk_mux_ldb(const char *name, void __iomem *reg,
144 			u8 shift, u8 width, const char * const *parents,
145 			int num_parents)
146 {
147 	return clk_register_mux(NULL, name, parents, num_parents,
148 			CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT, reg,
149 			shift, width, CLK_MUX_READ_ONLY, &imx_ccm_lock);
150 }
151 
152 static inline struct clk *imx_clk_fixed_factor(const char *name,
153 		const char *parent, unsigned int mult, unsigned int div)
154 {
155 	return clk_register_fixed_factor(NULL, name, parent,
156 			CLK_SET_RATE_PARENT, mult, div);
157 }
158 
159 static inline struct clk *imx_clk_divider(const char *name, const char *parent,
160 		void __iomem *reg, u8 shift, u8 width)
161 {
162 	return clk_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT,
163 			reg, shift, width, 0, &imx_ccm_lock);
164 }
165 
166 static inline struct clk_hw *imx_clk_hw_divider(const char *name,
167 						const char *parent,
168 						void __iomem *reg, u8 shift,
169 						u8 width)
170 {
171 	return clk_hw_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT,
172 				       reg, shift, width, 0, &imx_ccm_lock);
173 }
174 
175 static inline struct clk *imx_clk_divider_flags(const char *name,
176 		const char *parent, void __iomem *reg, u8 shift, u8 width,
177 		unsigned long flags)
178 {
179 	return clk_register_divider(NULL, name, parent, flags,
180 			reg, shift, width, 0, &imx_ccm_lock);
181 }
182 
183 static inline struct clk_hw *imx_clk_hw_divider_flags(const char *name,
184 						   const char *parent,
185 						   void __iomem *reg, u8 shift,
186 						   u8 width, unsigned long flags)
187 {
188 	return clk_hw_register_divider(NULL, name, parent, flags,
189 				       reg, shift, width, 0, &imx_ccm_lock);
190 }
191 
192 static inline struct clk *imx_clk_divider2(const char *name, const char *parent,
193 		void __iomem *reg, u8 shift, u8 width)
194 {
195 	return clk_register_divider(NULL, name, parent,
196 			CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
197 			reg, shift, width, 0, &imx_ccm_lock);
198 }
199 
200 static inline struct clk *imx_clk_divider2_flags(const char *name,
201 		const char *parent, void __iomem *reg, u8 shift, u8 width,
202 		unsigned long flags)
203 {
204 	return clk_register_divider(NULL, name, parent,
205 			flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
206 			reg, shift, width, 0, &imx_ccm_lock);
207 }
208 
209 static inline struct clk *imx_clk_gate(const char *name, const char *parent,
210 		void __iomem *reg, u8 shift)
211 {
212 	return clk_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
213 			shift, 0, &imx_ccm_lock);
214 }
215 
216 static inline struct clk *imx_clk_gate_flags(const char *name, const char *parent,
217 		void __iomem *reg, u8 shift, unsigned long flags)
218 {
219 	return clk_register_gate(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg,
220 			shift, 0, &imx_ccm_lock);
221 }
222 
223 static inline struct clk_hw *imx_clk_hw_gate(const char *name, const char *parent,
224 					     void __iomem *reg, u8 shift)
225 {
226 	return clk_hw_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
227 				    shift, 0, &imx_ccm_lock);
228 }
229 
230 static inline struct clk *imx_clk_gate_dis(const char *name, const char *parent,
231 		void __iomem *reg, u8 shift)
232 {
233 	return clk_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
234 			shift, CLK_GATE_SET_TO_DISABLE, &imx_ccm_lock);
235 }
236 
237 static inline struct clk *imx_clk_gate_dis_flags(const char *name, const char *parent,
238 		void __iomem *reg, u8 shift, unsigned long flags)
239 {
240 	return clk_register_gate(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg,
241 			shift, CLK_GATE_SET_TO_DISABLE, &imx_ccm_lock);
242 }
243 
244 static inline struct clk *imx_clk_gate2(const char *name, const char *parent,
245 		void __iomem *reg, u8 shift)
246 {
247 	return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
248 			shift, 0x3, 0, &imx_ccm_lock, NULL);
249 }
250 
251 static inline struct clk *imx_clk_gate2_flags(const char *name, const char *parent,
252 		void __iomem *reg, u8 shift, unsigned long flags)
253 {
254 	return clk_register_gate2(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg,
255 			shift, 0x3, 0, &imx_ccm_lock, NULL);
256 }
257 
258 static inline struct clk *imx_clk_gate2_shared(const char *name,
259 		const char *parent, void __iomem *reg, u8 shift,
260 		unsigned int *share_count)
261 {
262 	return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
263 			shift, 0x3, 0, &imx_ccm_lock, share_count);
264 }
265 
266 static inline struct clk *imx_clk_gate2_shared2(const char *name,
267 		const char *parent, void __iomem *reg, u8 shift,
268 		unsigned int *share_count)
269 {
270 	return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT |
271 				  CLK_OPS_PARENT_ENABLE, reg, shift, 0x3, 0,
272 				  &imx_ccm_lock, share_count);
273 }
274 
275 static inline struct clk *imx_clk_gate2_cgr(const char *name,
276 		const char *parent, void __iomem *reg, u8 shift, u8 cgr_val)
277 {
278 	return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
279 			shift, cgr_val, 0, &imx_ccm_lock, NULL);
280 }
281 
282 static inline struct clk *imx_clk_gate3(const char *name, const char *parent,
283 		void __iomem *reg, u8 shift)
284 {
285 	return clk_register_gate(NULL, name, parent,
286 			CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
287 			reg, shift, 0, &imx_ccm_lock);
288 }
289 
290 static inline struct clk *imx_clk_gate3_flags(const char *name,
291 		const char *parent, void __iomem *reg, u8 shift,
292 		unsigned long flags)
293 {
294 	return clk_register_gate(NULL, name, parent,
295 			flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
296 			reg, shift, 0, &imx_ccm_lock);
297 }
298 
299 static inline struct clk *imx_clk_gate4(const char *name, const char *parent,
300 		void __iomem *reg, u8 shift)
301 {
302 	return clk_register_gate2(NULL, name, parent,
303 			CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
304 			reg, shift, 0x3, 0, &imx_ccm_lock, NULL);
305 }
306 
307 static inline struct clk *imx_clk_gate4_flags(const char *name,
308 		const char *parent, void __iomem *reg, u8 shift,
309 		unsigned long flags)
310 {
311 	return clk_register_gate2(NULL, name, parent,
312 			flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
313 			reg, shift, 0x3, 0, &imx_ccm_lock, NULL);
314 }
315 
316 static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg,
317 			u8 shift, u8 width, const char * const *parents,
318 			int num_parents)
319 {
320 	return clk_register_mux(NULL, name, parents, num_parents,
321 			CLK_SET_RATE_NO_REPARENT, reg, shift,
322 			width, 0, &imx_ccm_lock);
323 }
324 
325 static inline struct clk *imx_clk_mux2(const char *name, void __iomem *reg,
326 			u8 shift, u8 width, const char * const *parents,
327 			int num_parents)
328 {
329 	return clk_register_mux(NULL, name, parents, num_parents,
330 			CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE,
331 			reg, shift, width, 0, &imx_ccm_lock);
332 }
333 
334 static inline struct clk_hw *imx_clk_hw_mux2(const char *name, void __iomem *reg,
335 					     u8 shift, u8 width,
336 					     const char * const *parents,
337 					     int num_parents)
338 {
339 	return clk_hw_register_mux(NULL, name, parents, num_parents,
340 				   CLK_SET_RATE_NO_REPARENT |
341 				   CLK_OPS_PARENT_ENABLE,
342 				   reg, shift, width, 0, &imx_ccm_lock);
343 }
344 
345 static inline struct clk *imx_clk_mux_flags(const char *name,
346 			void __iomem *reg, u8 shift, u8 width,
347 			const char * const *parents, int num_parents,
348 			unsigned long flags)
349 {
350 	return clk_register_mux(NULL, name, parents, num_parents,
351 			flags | CLK_SET_RATE_NO_REPARENT, reg, shift, width, 0,
352 			&imx_ccm_lock);
353 }
354 
355 static inline struct clk *imx_clk_mux2_flags(const char *name,
356 		void __iomem *reg, u8 shift, u8 width,
357 		const char * const *parents,
358 		int num_parents, unsigned long flags)
359 {
360 	return clk_register_mux(NULL, name, parents, num_parents,
361 			flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE,
362 			reg, shift, width, 0, &imx_ccm_lock);
363 }
364 
365 static inline struct clk_hw *imx_clk_hw_mux_flags(const char *name,
366 						  void __iomem *reg, u8 shift,
367 						  u8 width,
368 						  const char * const *parents,
369 						  int num_parents,
370 						  unsigned long flags)
371 {
372 	return clk_hw_register_mux(NULL, name, parents, num_parents,
373 				   flags | CLK_SET_RATE_NO_REPARENT,
374 				   reg, shift, width, 0, &imx_ccm_lock);
375 }
376 
377 struct clk *imx_clk_cpu(const char *name, const char *parent_name,
378 		struct clk *div, struct clk *mux, struct clk *pll,
379 		struct clk *step);
380 
381 struct clk *imx8m_clk_composite_flags(const char *name,
382 					const char * const *parent_names,
383 					int num_parents, void __iomem *reg,
384 					unsigned long flags);
385 
386 #define __imx8m_clk_composite(name, parent_names, reg, flags) \
387 	imx8m_clk_composite_flags(name, parent_names, \
388 		ARRAY_SIZE(parent_names), reg, \
389 		flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
390 
391 #define imx8m_clk_composite(name, parent_names, reg) \
392 	__imx8m_clk_composite(name, parent_names, reg, 0)
393 
394 #define imx8m_clk_composite_critical(name, parent_names, reg) \
395 	__imx8m_clk_composite(name, parent_names, reg, CLK_IS_CRITICAL)
396 
397 struct clk_hw *imx_clk_divider_gate(const char *name, const char *parent_name,
398 		unsigned long flags, void __iomem *reg, u8 shift, u8 width,
399 		u8 clk_divider_flags, const struct clk_div_table *table,
400 		spinlock_t *lock);
401 #endif
402