1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2019 DENX Software Engineering
4 * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
5 */
6#ifndef __MACH_IMX_CLK_H
7#define __MACH_IMX_CLK_H
8
9#include <linux/clk-provider.h>
10
11enum imx_pllv3_type {
12	IMX_PLLV3_GENERIC,
13	IMX_PLLV3_GENERICV2,
14	IMX_PLLV3_SYS,
15	IMX_PLLV3_USB,
16	IMX_PLLV3_USB_VF610,
17	IMX_PLLV3_AV,
18	IMX_PLLV3_ENET,
19	IMX_PLLV3_ENET_IMX7,
20	IMX_PLLV3_SYS_VF610,
21	IMX_PLLV3_DDR_IMX7,
22};
23
24enum imx_pll14xx_type {
25	PLL_1416X,
26	PLL_1443X,
27};
28
29/* NOTE: Rate table should be kept sorted in descending order. */
30struct imx_pll14xx_rate_table {
31	unsigned int rate;
32	unsigned int pdiv;
33	unsigned int mdiv;
34	unsigned int sdiv;
35	unsigned int kdiv;
36};
37
38struct imx_pll14xx_clk {
39	enum imx_pll14xx_type type;
40	const struct imx_pll14xx_rate_table *rate_table;
41	int rate_count;
42	int flags;
43};
44
45extern struct imx_pll14xx_clk imx_1416x_pll;
46extern struct imx_pll14xx_clk imx_1443x_pll;
47extern struct imx_pll14xx_clk imx_1443x_dram_pll;
48
49#define CLK_FRACN_GPPLL_INTEGER	BIT(0)
50#define CLK_FRACN_GPPLL_FRACN	BIT(1)
51
52/* NOTE: Rate table should be kept sorted in descending order. */
53struct imx_fracn_gppll_rate_table {
54	unsigned int rate;
55	unsigned int mfi;
56	unsigned int mfn;
57	unsigned int mfd;
58	unsigned int rdiv;
59	unsigned int odiv;
60};
61
62struct imx_fracn_gppll_clk {
63	const struct imx_fracn_gppll_rate_table *rate_table;
64	int rate_count;
65	int flags;
66};
67
68struct clk *imx_clk_fracn_gppll(const char *name, const char *parent_name, void __iomem *base,
69				const struct imx_fracn_gppll_clk *pll_clk);
70struct clk *imx_clk_fracn_gppll_integer(const char *name, const char *parent_name,
71					void __iomem *base,
72					const struct imx_fracn_gppll_clk *pll_clk);
73
74extern struct imx_fracn_gppll_clk imx_fracn_gppll;
75extern struct imx_fracn_gppll_clk imx_fracn_gppll_integer;
76
77struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
78			    void __iomem *base,
79			    const struct imx_pll14xx_clk *pll_clk);
80
81struct clk *clk_register_gate2(struct device *dev, const char *name,
82		const char *parent_name, unsigned long flags,
83		void __iomem *reg, u8 bit_idx, u8 cgr_val,
84		u8 clk_gate_flags, unsigned int *share_count);
85
86struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
87			  const char *parent_name, void __iomem *base,
88			  u32 div_mask);
89
90static inline struct clk *imx_clk_gate2(const char *name, const char *parent,
91					void __iomem *reg, u8 shift)
92{
93	return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
94			shift, 0x3, 0, NULL);
95}
96
97static inline struct clk *imx_clk_gate2_shared(const char *name,
98					       const char *parent,
99					       void __iomem *reg, u8 shift,
100					       unsigned int *share_count)
101{
102	return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
103				  shift, 0x3, 0, share_count);
104}
105
106static inline struct clk *imx_clk_gate2_shared2(const char *name,
107						const char *parent,
108						void __iomem *reg, u8 shift,
109						unsigned int *share_count)
110{
111	return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT |
112				  CLK_OPS_PARENT_ENABLE, reg, shift, 0x3, 0,
113				  share_count);
114}
115
116static inline struct clk *imx_clk_gate4(const char *name, const char *parent,
117		void __iomem *reg, u8 shift)
118{
119	return clk_register_gate2(NULL, name, parent,
120			CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
121			reg, shift, 0x3, 0, NULL);
122}
123
124static inline struct clk *imx_clk_gate4_flags(const char *name,
125		const char *parent, void __iomem *reg, u8 shift,
126		unsigned long flags)
127{
128	return clk_register_gate2(NULL, name, parent,
129			flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
130			reg, shift, 0x3, 0, NULL);
131}
132
133static inline struct clk *imx_clk_fixed_factor(const char *name,
134		const char *parent, unsigned int mult, unsigned int div)
135{
136	return clk_register_fixed_factor(NULL, name, parent,
137			CLK_SET_RATE_PARENT, mult, div);
138}
139
140static inline struct clk *imx_clk_divider(const char *name, const char *parent,
141		void __iomem *reg, u8 shift, u8 width)
142{
143	return clk_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT,
144			reg, shift, width, 0);
145}
146
147static inline struct clk *
148imx_clk_busy_divider(const char *name, const char *parent, void __iomem *reg,
149		     u8 shift, u8 width, void __iomem *busy_reg, u8 busy_shift)
150{
151	return clk_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT,
152			reg, shift, width, 0);
153}
154
155static inline struct clk *imx_clk_divider2(const char *name, const char *parent,
156		void __iomem *reg, u8 shift, u8 width)
157{
158	return clk_register_divider(NULL, name, parent,
159			CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
160			reg, shift, width, 0);
161}
162
163struct clk *imx_clk_pfd(const char *name, const char *parent_name,
164			void __iomem *reg, u8 idx);
165
166struct clk *imx_clk_fixup_mux(const char *name, void __iomem *reg,
167			      u8 shift, u8 width, const char * const *parents,
168			      int num_parents, void (*fixup)(u32 *val));
169
170static inline struct clk *imx_clk_mux_flags(const char *name,
171			void __iomem *reg, u8 shift, u8 width,
172			const char * const *parents, int num_parents,
173			unsigned long flags)
174{
175	return clk_register_mux(NULL, name, parents, num_parents,
176				flags | CLK_SET_RATE_NO_REPARENT, reg, shift,
177				width, 0);
178}
179
180static inline struct clk *imx_clk_mux2_flags(const char *name,
181		void __iomem *reg, u8 shift, u8 width,
182		const char * const *parents,
183		int num_parents, unsigned long flags)
184{
185	return clk_register_mux(NULL, name, parents, num_parents,
186			flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE,
187			reg, shift, width, 0);
188}
189
190static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg,
191			u8 shift, u8 width, const char * const *parents,
192			int num_parents)
193{
194	return clk_register_mux(NULL, name, parents, num_parents,
195			CLK_SET_RATE_NO_REPARENT, reg, shift,
196			width, 0);
197}
198
199static inline struct clk *
200imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift, u8 width,
201		 void __iomem *busy_reg, u8 busy_shift,
202		 const char * const *parents, int num_parents)
203{
204	return clk_register_mux(NULL, name, parents, num_parents,
205			CLK_SET_RATE_NO_REPARENT, reg, shift,
206			width, 0);
207}
208
209static inline struct clk *imx_clk_mux2(const char *name, void __iomem *reg,
210			u8 shift, u8 width, const char * const *parents,
211			int num_parents)
212{
213	return clk_register_mux(NULL, name, parents, num_parents,
214			CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE,
215			reg, shift, width, 0);
216}
217
218static inline struct clk *imx_clk_gate(const char *name, const char *parent,
219		void __iomem *reg, u8 shift)
220{
221	return clk_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
222			shift, 0, NULL);
223}
224
225static inline struct clk *imx_clk_gate_flags(const char *name, const char *parent,
226		void __iomem *reg, u8 shift, unsigned long flags)
227{
228	return clk_register_gate(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg,
229			shift, 0, NULL);
230}
231
232static inline struct clk *imx_clk_gate3(const char *name, const char *parent,
233		void __iomem *reg, u8 shift)
234{
235	return clk_register_gate(NULL, name, parent,
236			CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
237			reg, shift, 0, NULL);
238}
239
240struct clk *imx8m_clk_composite_flags(const char *name,
241		const char * const *parent_names,
242		int num_parents, void __iomem *reg, unsigned long flags);
243
244#define __imx8m_clk_composite(name, parent_names, reg, flags) \
245	imx8m_clk_composite_flags(name, parent_names, \
246		ARRAY_SIZE(parent_names), reg, \
247		flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
248
249#define imx8m_clk_composite(name, parent_names, reg) \
250	__imx8m_clk_composite(name, parent_names, reg, 0)
251
252#define imx8m_clk_composite_critical(name, parent_names, reg) \
253	__imx8m_clk_composite(name, parent_names, reg, CLK_IS_CRITICAL)
254
255struct clk *imx93_clk_composite_flags(const char *name,
256				      const char * const *parent_names,
257				      int num_parents,
258				      void __iomem *reg,
259				      u32 domain_id,
260				      unsigned long flags);
261#define imx93_clk_composite(name, parent_names, num_parents, reg, domain_id) \
262	imx93_clk_composite_flags(name, parent_names, num_parents, reg, domain_id \
263				  CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
264
265struct clk *imx93_clk_gate(struct device *dev, const char *name, const char *parent_name,
266			   unsigned long flags, void __iomem *reg, u32 bit_idx, u32 val,
267			   u32 mask, u32 domain_id, unsigned int *share_count);
268
269#endif /* __MACH_IMX_CLK_H */
270