xref: /freebsd/sys/arm64/freescale/imx/imx_ccm_clk.h (revision 4e8d558c)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2020 Oleksandr Tymoshenko <gonzo@FreeBSD.org>
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 THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  * $FreeBSD$
28  */
29 
30 #ifndef	IMX6_CCM_CLK_H
31 #define	IMX6_CCM_CLK_H
32 
33 #include <dev/extres/clk/clk.h>
34 #include <dev/extres/clk/clk_div.h>
35 #include <dev/extres/clk/clk_fixed.h>
36 #include <dev/extres/clk/clk_gate.h>
37 #include <dev/extres/clk/clk_link.h>
38 
39 enum imx_clk_type {
40 	IMX_CLK_UNDEFINED = 0,
41 	IMX_CLK_FIXED,
42 	IMX_CLK_LINK,
43 	IMX_CLK_MUX,
44 	IMX_CLK_GATE,
45 	IMX_CLK_COMPOSITE,
46 	IMX_CLK_SSCG_PLL,
47 	IMX_CLK_FRAC_PLL,
48 	IMX_CLK_DIV,
49 };
50 
51 struct imx_clk {
52 	enum imx_clk_type	type;
53 	union {
54 		struct clk_fixed_def		*fixed;
55 		struct clk_link_def		*link;
56 		struct imx_clk_mux_def		*mux;
57 		struct imx_clk_gate_def		*gate;
58 		struct imx_clk_composite_def	*composite;
59 		struct imx_clk_sscg_pll_def	*sscg_pll;
60 		struct imx_clk_frac_pll_def	*frac_pll;
61 		struct clk_div_def		*div;
62 	} clk;
63 };
64 
65 /* Linked clock. */
66 #define	LINK(_id, _name)						\
67 {									\
68 	.type = IMX_CLK_LINK,						\
69 	.clk.link = &(struct clk_link_def) {				\
70 		.clkdef.id = _id,					\
71 		.clkdef.name = _name,					\
72 		.clkdef.parent_names = NULL,				\
73 		.clkdef.parent_cnt = 0,					\
74 		.clkdef.flags = CLK_NODE_STATIC_STRINGS,		\
75 	},								\
76 }
77 
78 /* Complex clock without divider (multiplexer only). */
79 #define MUX(_id, _name, _pn, _f,  _mo, _ms, _mw)			\
80 {									\
81 	.type = IMX_CLK_MUX,						\
82 	.clk.mux = &(struct imx_clk_mux_def) {				\
83 		.clkdef.id = _id,					\
84 		.clkdef.name = _name,					\
85 		.clkdef.parent_names = _pn,				\
86 		.clkdef.parent_cnt = nitems(_pn),			\
87 		.clkdef.flags = CLK_NODE_STATIC_STRINGS,		\
88 		.offset = _mo,						\
89 		.shift = _ms,						\
90 		.width = _mw,						\
91 		.mux_flags = _f, 					\
92 	},								\
93 }
94 
95 /* Fixed frequency clock */
96 #define	FIXED(_id, _name, _freq)					\
97 {									\
98 	.type = IMX_CLK_FIXED,						\
99 	.clk.fixed = &(struct clk_fixed_def) {				\
100 		.clkdef.id = _id,					\
101 		.clkdef.name = _name,					\
102 		.clkdef.flags = CLK_NODE_STATIC_STRINGS,		\
103 		.freq = _freq,						\
104 	},								\
105 }
106 
107 /* Fixed factor multipier/divider. */
108 #define	FFACT(_id, _name, _pname, _mult, _div)				\
109 {									\
110 	.type = IMX_CLK_FIXED,						\
111 	.clk.fixed = &(struct clk_fixed_def) {				\
112 		.clkdef.id = _id,					\
113 		.clkdef.name = _name,					\
114 		.clkdef.parent_names = (const char *[]){_pname},	\
115 		.clkdef.parent_cnt = 1,					\
116 		.clkdef.flags = CLK_NODE_STATIC_STRINGS,		\
117 		.mult = _mult,						\
118 		.div = _div,						\
119 	},								\
120 }
121 
122 /* Clock gate */
123 #define	GATE(_id, _name, _pname, _o, _shift)				\
124 {									\
125 	.type = IMX_CLK_GATE,						\
126 	.clk.gate = &(struct imx_clk_gate_def) {			\
127 		.clkdef.id = _id,					\
128 		.clkdef.name = _name,					\
129 		.clkdef.parent_names = (const char *[]){_pname},	\
130 		.clkdef.parent_cnt = 1,					\
131 		.clkdef.flags = CLK_NODE_STATIC_STRINGS,		\
132 		.offset = _o,						\
133 		.shift = _shift,					\
134 		.mask = 1,						\
135 	},								\
136 }
137 
138 /* Root clock gate */
139 #define	ROOT_GATE(_id, _name, _pname, _reg)				\
140 {									\
141 	.type = IMX_CLK_GATE,						\
142 	.clk.gate = &(struct imx_clk_gate_def) {			\
143 		.clkdef.id = _id,					\
144 		.clkdef.name = _name,					\
145 		.clkdef.parent_names = (const char *[]){_pname},	\
146 		.clkdef.parent_cnt = 1,					\
147 		.clkdef.flags = CLK_NODE_STATIC_STRINGS,		\
148 		.offset = _reg,						\
149 		.shift = 0,						\
150 		.mask = 3,						\
151 	},								\
152 }
153 
154 /* Composite clock with GATE, MUX, PRE_DIV, and POST_DIV */
155 #define COMPOSITE(_id, _name, _pn, _o, _flags)				\
156 {									\
157 	.type = IMX_CLK_COMPOSITE,					\
158 	.clk.composite = &(struct imx_clk_composite_def) {		\
159 		.clkdef.id = _id,					\
160 		.clkdef.name = _name,					\
161 		.clkdef.parent_names = _pn,				\
162 		.clkdef.parent_cnt = nitems(_pn),			\
163 		.clkdef.flags = CLK_NODE_STATIC_STRINGS,		\
164 		.offset = _o,						\
165 		.flags = _flags,					\
166 	},								\
167 }
168 
169 /* SSCG PLL */
170 #define SSCG_PLL(_id, _name, _pn, _o)					\
171 {									\
172 	.type = IMX_CLK_SSCG_PLL,					\
173 	.clk.composite = &(struct imx_clk_composite_def) {		\
174 		.clkdef.id = _id,					\
175 		.clkdef.name = _name,					\
176 		.clkdef.parent_names = _pn,				\
177 		.clkdef.parent_cnt = nitems(_pn),			\
178 		.clkdef.flags = CLK_NODE_STATIC_STRINGS,		\
179 		.offset = _o,						\
180 	},								\
181 }
182 
183 /* Fractional PLL */
184 #define FRAC_PLL(_id, _name, _pname, _o)				\
185 {									\
186 	.type = IMX_CLK_FRAC_PLL,					\
187 	.clk.frac_pll = &(struct imx_clk_frac_pll_def) {		\
188 		.clkdef.id = _id,					\
189 		.clkdef.name = _name,					\
190 		.clkdef.parent_names = (const char *[]){_pname},	\
191 		.clkdef.parent_cnt = 1,					\
192 		.clkdef.flags = CLK_NODE_STATIC_STRINGS,		\
193 		.offset = _o,						\
194 	},								\
195 }
196 
197 #define DIV(_id, _name, _pname, _o, _shift, _width)			\
198 {									\
199 	.type = IMX_CLK_DIV,						\
200 	.clk.div = &(struct clk_div_def) {				\
201 		.clkdef.id = _id,					\
202 		.clkdef.name = _name,					\
203 		.clkdef.parent_names = (const char *[]){_pname},	\
204 		.clkdef.parent_cnt = 1,					\
205 		.clkdef.flags = CLK_NODE_STATIC_STRINGS,		\
206 		.offset = _o,						\
207 		.i_shift = _shift,					\
208 		.i_width = _width,					\
209 	},								\
210 }
211 
212 #endif
213