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 
11 enum 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 
24 enum imx_pll14xx_type {
25 	PLL_1416X,
26 	PLL_1443X,
27 };
28 
29 /* NOTE: Rate table should be kept sorted in descending order. */
30 struct 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 
38 struct 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 
45 extern struct imx_pll14xx_clk imx_1416x_pll;
46 extern struct imx_pll14xx_clk imx_1443x_pll;
47 extern struct imx_pll14xx_clk imx_1443x_dram_pll;
48 
49 struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
50 			    void __iomem *base,
51 			    const struct imx_pll14xx_clk *pll_clk);
52 
53 struct clk *clk_register_gate2(struct device *dev, const char *name,
54 		const char *parent_name, unsigned long flags,
55 		void __iomem *reg, u8 bit_idx, u8 cgr_val,
56 		u8 clk_gate_flags, unsigned int *share_count);
57 
58 struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
59 			  const char *parent_name, void __iomem *base,
60 			  u32 div_mask);
61 
imx_clk_gate2(const char * name,const char * parent,void __iomem * reg,u8 shift)62 static inline struct clk *imx_clk_gate2(const char *name, const char *parent,
63 					void __iomem *reg, u8 shift)
64 {
65 	return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
66 			shift, 0x3, 0, NULL);
67 }
68 
imx_clk_gate2_shared(const char * name,const char * parent,void __iomem * reg,u8 shift,unsigned int * share_count)69 static inline struct clk *imx_clk_gate2_shared(const char *name,
70 					       const char *parent,
71 					       void __iomem *reg, u8 shift,
72 					       unsigned int *share_count)
73 {
74 	return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
75 				  shift, 0x3, 0, share_count);
76 }
77 
imx_clk_gate2_shared2(const char * name,const char * parent,void __iomem * reg,u8 shift,unsigned int * share_count)78 static inline struct clk *imx_clk_gate2_shared2(const char *name,
79 						const char *parent,
80 						void __iomem *reg, u8 shift,
81 						unsigned int *share_count)
82 {
83 	return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT |
84 				  CLK_OPS_PARENT_ENABLE, reg, shift, 0x3, 0,
85 				  share_count);
86 }
87 
imx_clk_gate4(const char * name,const char * parent,void __iomem * reg,u8 shift)88 static inline struct clk *imx_clk_gate4(const char *name, const char *parent,
89 		void __iomem *reg, u8 shift)
90 {
91 	return clk_register_gate2(NULL, name, parent,
92 			CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
93 			reg, shift, 0x3, 0, NULL);
94 }
95 
imx_clk_gate4_flags(const char * name,const char * parent,void __iomem * reg,u8 shift,unsigned long flags)96 static inline struct clk *imx_clk_gate4_flags(const char *name,
97 		const char *parent, void __iomem *reg, u8 shift,
98 		unsigned long flags)
99 {
100 	return clk_register_gate2(NULL, name, parent,
101 			flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
102 			reg, shift, 0x3, 0, NULL);
103 }
104 
imx_clk_fixed_factor(const char * name,const char * parent,unsigned int mult,unsigned int div)105 static inline struct clk *imx_clk_fixed_factor(const char *name,
106 		const char *parent, unsigned int mult, unsigned int div)
107 {
108 	return clk_register_fixed_factor(NULL, name, parent,
109 			CLK_SET_RATE_PARENT, mult, div);
110 }
111 
imx_clk_divider(const char * name,const char * parent,void __iomem * reg,u8 shift,u8 width)112 static inline struct clk *imx_clk_divider(const char *name, const char *parent,
113 		void __iomem *reg, u8 shift, u8 width)
114 {
115 	return clk_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT,
116 			reg, shift, width, 0);
117 }
118 
119 static inline struct clk *
imx_clk_busy_divider(const char * name,const char * parent,void __iomem * reg,u8 shift,u8 width,void __iomem * busy_reg,u8 busy_shift)120 imx_clk_busy_divider(const char *name, const char *parent, void __iomem *reg,
121 		     u8 shift, u8 width, void __iomem *busy_reg, u8 busy_shift)
122 {
123 	return clk_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT,
124 			reg, shift, width, 0);
125 }
126 
imx_clk_divider2(const char * name,const char * parent,void __iomem * reg,u8 shift,u8 width)127 static inline struct clk *imx_clk_divider2(const char *name, const char *parent,
128 		void __iomem *reg, u8 shift, u8 width)
129 {
130 	return clk_register_divider(NULL, name, parent,
131 			CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
132 			reg, shift, width, 0);
133 }
134 
135 struct clk *imx_clk_pfd(const char *name, const char *parent_name,
136 			void __iomem *reg, u8 idx);
137 
138 struct clk *imx_clk_fixup_mux(const char *name, void __iomem *reg,
139 			      u8 shift, u8 width, const char * const *parents,
140 			      int num_parents, void (*fixup)(u32 *val));
141 
imx_clk_mux_flags(const char * name,void __iomem * reg,u8 shift,u8 width,const char * const * parents,int num_parents,unsigned long flags)142 static inline struct clk *imx_clk_mux_flags(const char *name,
143 			void __iomem *reg, u8 shift, u8 width,
144 			const char * const *parents, int num_parents,
145 			unsigned long flags)
146 {
147 	return clk_register_mux(NULL, name, parents, num_parents,
148 				flags | CLK_SET_RATE_NO_REPARENT, reg, shift,
149 				width, 0);
150 }
151 
imx_clk_mux2_flags(const char * name,void __iomem * reg,u8 shift,u8 width,const char * const * parents,int num_parents,unsigned long flags)152 static inline struct clk *imx_clk_mux2_flags(const char *name,
153 		void __iomem *reg, u8 shift, u8 width,
154 		const char * const *parents,
155 		int num_parents, unsigned long flags)
156 {
157 	return clk_register_mux(NULL, name, parents, num_parents,
158 			flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE,
159 			reg, shift, width, 0);
160 }
161 
imx_clk_mux(const char * name,void __iomem * reg,u8 shift,u8 width,const char * const * parents,int num_parents)162 static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg,
163 			u8 shift, u8 width, const char * const *parents,
164 			int num_parents)
165 {
166 	return clk_register_mux(NULL, name, parents, num_parents,
167 			CLK_SET_RATE_NO_REPARENT, reg, shift,
168 			width, 0);
169 }
170 
171 static inline struct clk *
imx_clk_busy_mux(const char * name,void __iomem * reg,u8 shift,u8 width,void __iomem * busy_reg,u8 busy_shift,const char * const * parents,int num_parents)172 imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift, u8 width,
173 		 void __iomem *busy_reg, u8 busy_shift,
174 		 const char * const *parents, int num_parents)
175 {
176 	return clk_register_mux(NULL, name, parents, num_parents,
177 			CLK_SET_RATE_NO_REPARENT, reg, shift,
178 			width, 0);
179 }
180 
imx_clk_mux2(const char * name,void __iomem * reg,u8 shift,u8 width,const char * const * parents,int num_parents)181 static inline struct clk *imx_clk_mux2(const char *name, void __iomem *reg,
182 			u8 shift, u8 width, const char * const *parents,
183 			int num_parents)
184 {
185 	return clk_register_mux(NULL, name, parents, num_parents,
186 			CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE,
187 			reg, shift, width, 0);
188 }
189 
imx_clk_gate(const char * name,const char * parent,void __iomem * reg,u8 shift)190 static inline struct clk *imx_clk_gate(const char *name, const char *parent,
191 		void __iomem *reg, u8 shift)
192 {
193 	return clk_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
194 			shift, 0, NULL);
195 }
196 
imx_clk_gate_flags(const char * name,const char * parent,void __iomem * reg,u8 shift,unsigned long flags)197 static inline struct clk *imx_clk_gate_flags(const char *name, const char *parent,
198 		void __iomem *reg, u8 shift, unsigned long flags)
199 {
200 	return clk_register_gate(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg,
201 			shift, 0, NULL);
202 }
203 
imx_clk_gate3(const char * name,const char * parent,void __iomem * reg,u8 shift)204 static inline struct clk *imx_clk_gate3(const char *name, const char *parent,
205 		void __iomem *reg, u8 shift)
206 {
207 	return clk_register_gate(NULL, name, parent,
208 			CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
209 			reg, shift, 0, NULL);
210 }
211 
212 struct clk *imx8m_clk_composite_flags(const char *name,
213 		const char * const *parent_names,
214 		int num_parents, void __iomem *reg, unsigned long flags);
215 
216 #define __imx8m_clk_composite(name, parent_names, reg, flags) \
217 	imx8m_clk_composite_flags(name, parent_names, \
218 		ARRAY_SIZE(parent_names), reg, \
219 		flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
220 
221 #define imx8m_clk_composite(name, parent_names, reg) \
222 	__imx8m_clk_composite(name, parent_names, reg, 0)
223 
224 #define imx8m_clk_composite_critical(name, parent_names, reg) \
225 	__imx8m_clk_composite(name, parent_names, reg, CLK_IS_CRITICAL)
226 
227 #endif /* __MACH_IMX_CLK_H */
228