xref: /netbsd-src/sys/arch/arm/nxp/imx6_ccmvar.h (revision 5fd4005d8b7a68771ba913bcb5e99de942b2e13b)
1 /*	$NetBSD: imx6_ccmvar.h,v 1.3 2023/05/04 13:25:07 bouyer Exp $	*/
2 /*
3  * Copyright (c) 2012,2019  Genetec Corporation.  All rights reserved.
4  * Written by Hashimoto Kenichi for Genetec Corporation.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GENETEC CORPORATION
19  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #ifndef	_ARM_NXP_IMX6_CCMVAR_H_
29 #define	_ARM_NXP_IMX6_CCMVAR_H_
30 
31 #include <dev/clk/clk.h>
32 #include <dev/clk/clk_backend.h>
33 
34 struct imx6ccm_softc {
35 	device_t sc_dev;
36 	bus_space_tag_t sc_iot;
37 	bus_space_handle_t sc_ioh;
38 	bus_space_handle_t sc_ioh_analog;
39 
40 	struct clk_domain sc_clkdom;
41 	struct imx6_clk *sc_imx6_clks;
42 	int sc_imx6_clksize;
43 };
44 
45 struct imxccm_init_parent;
46 
47 void imx6ccm_attach_common(device_t, struct imx6_clk *, int,
48     struct imxccm_init_parent *);
49 
50 struct clk *imx6_get_clock(struct imx6ccm_softc *, const char *);
51 struct imx6_clk *imx6_clk_find(struct imx6ccm_softc *sc, const char *);
52 
53 struct imxccm_init_parent {
54 	const char *clock;
55 	const char *parent;
56 };
57 
58 
59 enum imx6_clk_type {
60 	IMX6_CLK_FIXED,
61 	IMX6_CLK_FIXED_FACTOR,
62 	IMX6_CLK_PLL,
63 	IMX6_CLK_MUX,
64 	IMX6_CLK_GATE,
65 	IMX6_CLK_PFD,
66 	IMX6_CLK_DIV,
67 };
68 
69 enum imx6_clk_reg {
70 	IMX6_CLK_REG_CCM,
71 	IMX6_CLK_REG_CCM_ANALOG,
72 };
73 
74 enum imx6_clk_pll_type {
75 	IMX6_CLK_PLL_GENERIC,
76 	IMX6_CLK_PLL_SYS,
77 	IMX6_CLK_PLL_USB,
78 	IMX6_CLK_PLL_AUDIO_VIDEO,
79 	IMX6_CLK_PLL_ENET,
80 };
81 
82 enum imx6_clk_div_type {
83 	IMX6_CLK_DIV_NORMAL,
84 	IMX6_CLK_DIV_BUSY,
85 	IMX6_CLK_DIV_TABLE,
86 };
87 
88 enum imx6_clk_mux_type {
89 	IMX6_CLK_MUX_NORMAL,
90 	IMX6_CLK_MUX_BUSY,
91 };
92 
93 struct imx6_clk_fixed {
94 	u_int rate;
95 };
96 
97 struct imx6_clk_fixed_factor {
98 	u_int div;
99 	u_int mult;
100 };
101 
102 struct imx6_clk_pfd {
103 	uint32_t reg;
104 	int index;
105 };
106 
107 struct imx6_clk_pll {
108 	enum imx6_clk_pll_type type;
109 	uint32_t reg;
110 	uint32_t mask;
111 	uint32_t powerdown;
112 	unsigned long ref;
113 };
114 
115 struct imx6_clk_div {
116 	enum imx6_clk_div_type type;
117 	enum imx6_clk_reg base;
118 	uint32_t reg;
119 	uint32_t mask;
120 	uint32_t busy_reg;
121 	uint32_t busy_mask;
122 	const int *tbl;
123 };
124 
125 struct imx6_clk_mux {
126 	enum imx6_clk_mux_type type;
127 	enum imx6_clk_reg base;
128 	uint32_t reg;
129 	uint32_t mask;
130 	const char **parents;
131 	u_int nparents;
132 	uint32_t busy_reg;
133 	uint32_t busy_mask;
134 };
135 
136 struct imx6_clk_gate {
137 	enum imx6_clk_reg base;
138 	uint32_t reg;
139 	uint32_t mask;
140 	uint32_t exclusive_mask;
141 };
142 
143 struct imx6_clk {
144 	struct clk base;		/* must be first */
145 
146 	const char *parent;
147 	u_int refcnt;
148 
149 	enum imx6_clk_type type;
150 	union {
151 		struct imx6_clk_fixed fixed;
152 		struct imx6_clk_fixed_factor fixed_factor;
153 		struct imx6_clk_pfd pfd;
154 		struct imx6_clk_pll pll;
155 		struct imx6_clk_div div;
156 		struct imx6_clk_mux mux;
157 		struct imx6_clk_gate gate;
158 	} clk;
159 };
160 
161 #define CLK_FIXED(_name, _rate) {				\
162 	.base = { .name = (_name) },				\
163 	.type = IMX6_CLK_FIXED,					\
164 	.clk = {						\
165 		.fixed = {					\
166 			.rate = (_rate),			\
167 		}						\
168 	}							\
169 }
170 
171 #define CLK_FIXED_FACTOR(_name, _parent, _div, _mult) {		\
172 	.base = { .name = (_name) },				\
173 	.type = IMX6_CLK_FIXED_FACTOR,				\
174 	.parent = (_parent),					\
175 	.clk = {						\
176 		.fixed_factor = {				\
177 			.div = (_div),				\
178 			.mult = (_mult),			\
179 		}						\
180 	}							\
181 }
182 
183 #define CLK_PFD(_name, _parent, _reg, _index) {			\
184 	.base = { .name = (_name) },				\
185 	.type = IMX6_CLK_PFD,					\
186 	.parent = (_parent),					\
187 	.clk = {						\
188 		.pfd = {					\
189 			.reg = (CCM_ANALOG_##_reg),		\
190 			.index = (_index),			\
191 		}						\
192 	}							\
193 }
194 
195 #define CLK_PLL(_name, _parent, _type, _reg, _mask, _powerdown, _ref) { \
196 	.base = { .name = (_name) },				\
197 	.type = IMX6_CLK_PLL,					\
198 	.parent = (_parent),					\
199 	.clk = {						\
200 		.pll = {					\
201 			.type = (IMX6_CLK_PLL_##_type),		\
202 			.reg = (CCM_ANALOG_##_reg),		\
203 			.mask = (CCM_ANALOG_##_reg##_##_mask),	\
204 			.powerdown = (CCM_ANALOG_##_reg##_##_powerdown), \
205 			.ref = (_ref),				\
206 		}						\
207 	}							\
208 }
209 
210 #define CLK_DIV(_name, _parent, _reg, _mask) {			\
211 	.base = { .name = (_name) },				\
212 	.type = IMX6_CLK_DIV,					\
213 	.parent = (_parent),					\
214 	.clk = {						\
215 		.div = {					\
216 			.type = (IMX6_CLK_DIV_NORMAL),		\
217 			.base = (IMX6_CLK_REG_CCM),		\
218 			.reg = (CCM_##_reg),			\
219 			.mask = (CCM_##_reg##_##_mask),		\
220 		}						\
221 	}							\
222 }
223 
224 #define CLK_DIV_BUSY(_name, _parent, _reg, _mask, _busy_reg, _busy_mask) { \
225 	.base = { .name = (_name) },				\
226 	.type = IMX6_CLK_DIV,					\
227 	.parent = (_parent),					\
228 	.clk = {						\
229 		.div = {					\
230 			.type = (IMX6_CLK_DIV_BUSY),		\
231 			.base = (IMX6_CLK_REG_CCM),		\
232 			.reg = (CCM_##_reg),			\
233 			.mask = (CCM_##_reg##_##_mask),	\
234 			.busy_reg = (CCM_##_busy_reg),		\
235 			.busy_mask = (CCM_##_busy_reg##_##_busy_mask) \
236 		}						\
237 	}							\
238 }
239 
240 #define CLK_DIV_TABLE(_name, _parent, _reg, _mask, _tbl) {	\
241 	.base = { .name = (_name) },				\
242 	.type = IMX6_CLK_DIV,					\
243 	.parent = (_parent),					\
244 	.clk = {						\
245 		.div = {					\
246 			.type = (IMX6_CLK_DIV_TABLE),		\
247 			.base = (IMX6_CLK_REG_CCM_ANALOG),	\
248 			.reg = (CCM_ANALOG_##_reg),		\
249 			.mask = (CCM_ANALOG_##_reg##_##_mask),	\
250 			.tbl = (_tbl)				\
251 		}						\
252 	}							\
253 }
254 
255 #define CLK_MUX(_name, _parents, _base, _reg, _mask) {		\
256 	.base = { .name = (_name), .flags = CLK_SET_RATE_PARENT }, \
257 	.type = IMX6_CLK_MUX,					\
258 	.clk = {						\
259 		.mux = {					\
260 			.type = (IMX6_CLK_MUX_NORMAL),		\
261 			.base = (IMX6_CLK_REG_##_base),		\
262 			.reg = (_base##_##_reg),		\
263 			.mask = (_base##_##_reg##_##_mask),	\
264 			.parents = (_parents),			\
265 			.nparents = __arraycount(_parents)	\
266 		}						\
267 	}							\
268 }
269 
270 #define CLK_MUX_BUSY(_name, _parents, _reg, _mask, _busy_reg, _busy_mask) { \
271 	.base = { .name = (_name), .flags = CLK_SET_RATE_PARENT }, \
272 	.type = IMX6_CLK_MUX,					\
273 	.clk = {						\
274 		.mux = {					\
275 			.type = (IMX6_CLK_MUX_BUSY),		\
276 			.base = (IMX6_CLK_REG_CCM),		\
277 			.reg = (CCM_##_reg),			\
278 			.mask = (CCM_##_reg##_##_mask),		\
279 			.parents = (_parents),			\
280 			.nparents = __arraycount(_parents),	\
281 			.busy_reg = (CCM_##_busy_reg),		\
282 			.busy_mask = (CCM_##_busy_reg##_##_busy_mask) \
283 		}						\
284 	}							\
285 }
286 
287 #define CLK_GATE(_name, _parent, _base, _reg, _mask) {		\
288 	.base = { .name = (_name), .flags = CLK_SET_RATE_PARENT }, \
289 	.type = IMX6_CLK_GATE,					\
290 	.parent = (_parent),					\
291 	.clk = {						\
292 		.gate = {					\
293 			.base = (IMX6_CLK_REG_##_base),		\
294 			.reg = (_base##_##_reg),		\
295 			.mask = (_base##_##_reg##_##_mask),	\
296 			.exclusive_mask = 0			\
297 		}						\
298 	}							\
299 }
300 
301 #define CLK_GATE_EXCLUSIVE(_name, _parent, _base, _reg, _mask, _exclusive_mask) {  \
302 	.base = { .name = (_name), .flags = CLK_SET_RATE_PARENT }, \
303 	.type = IMX6_CLK_GATE,					\
304 	.parent = (_parent),					\
305 	.clk = {						\
306 		.gate = {					\
307 			.base = (IMX6_CLK_REG_##_base),		\
308 			.reg = (_base##_##_reg),		\
309 			.mask = (_base##_##_reg##_##_mask),     \
310 			.exclusive_mask = (_base##_##_reg##_##_exclusive_mask) \
311 		}						\
312 	}							\
313 }
314 
315 #endif	/* _ARM_NXP_IMX6_CCMVAR_H_ */
316