xref: /freebsd/sys/arm64/freescale/imx/imx_ccm_clk.h (revision 069ac184)
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 
28 #ifndef	IMX6_CCM_CLK_H
29 #define	IMX6_CCM_CLK_H
30 
31 #include <dev/extres/clk/clk.h>
32 #include <dev/extres/clk/clk_div.h>
33 #include <dev/extres/clk/clk_fixed.h>
34 #include <dev/extres/clk/clk_gate.h>
35 #include <dev/extres/clk/clk_link.h>
36 
37 enum imx_clk_type {
38 	IMX_CLK_UNDEFINED = 0,
39 	IMX_CLK_FIXED,
40 	IMX_CLK_LINK,
41 	IMX_CLK_MUX,
42 	IMX_CLK_GATE,
43 	IMX_CLK_COMPOSITE,
44 	IMX_CLK_SSCG_PLL,
45 	IMX_CLK_FRAC_PLL,
46 	IMX_CLK_DIV,
47 };
48 
49 struct imx_clk {
50 	enum imx_clk_type	type;
51 	union {
52 		struct clk_fixed_def		*fixed;
53 		struct clk_link_def		*link;
54 		struct imx_clk_mux_def		*mux;
55 		struct imx_clk_gate_def		*gate;
56 		struct imx_clk_composite_def	*composite;
57 		struct imx_clk_sscg_pll_def	*sscg_pll;
58 		struct imx_clk_frac_pll_def	*frac_pll;
59 		struct clk_div_def		*div;
60 	} clk;
61 };
62 
63 /* Linked clock. */
64 #define	LINK(_id, _name)						\
65 {									\
66 	.type = IMX_CLK_LINK,						\
67 	.clk.link = &(struct clk_link_def) {				\
68 		.clkdef.id = _id,					\
69 		.clkdef.name = _name,					\
70 		.clkdef.parent_names = NULL,				\
71 		.clkdef.parent_cnt = 0,					\
72 		.clkdef.flags = CLK_NODE_STATIC_STRINGS,		\
73 	},								\
74 }
75 
76 /* Complex clock without divider (multiplexer only). */
77 #define MUX(_id, _name, _pn, _f,  _mo, _ms, _mw)			\
78 {									\
79 	.type = IMX_CLK_MUX,						\
80 	.clk.mux = &(struct imx_clk_mux_def) {				\
81 		.clkdef.id = _id,					\
82 		.clkdef.name = _name,					\
83 		.clkdef.parent_names = _pn,				\
84 		.clkdef.parent_cnt = nitems(_pn),			\
85 		.clkdef.flags = CLK_NODE_STATIC_STRINGS,		\
86 		.offset = _mo,						\
87 		.shift = _ms,						\
88 		.width = _mw,						\
89 		.mux_flags = _f, 					\
90 	},								\
91 }
92 
93 /* Fixed frequency clock */
94 #define	FIXED(_id, _name, _freq)					\
95 {									\
96 	.type = IMX_CLK_FIXED,						\
97 	.clk.fixed = &(struct clk_fixed_def) {				\
98 		.clkdef.id = _id,					\
99 		.clkdef.name = _name,					\
100 		.clkdef.flags = CLK_NODE_STATIC_STRINGS,		\
101 		.freq = _freq,						\
102 	},								\
103 }
104 
105 /* Fixed factor multipier/divider. */
106 #define	FFACT(_id, _name, _pname, _mult, _div)				\
107 {									\
108 	.type = IMX_CLK_FIXED,						\
109 	.clk.fixed = &(struct clk_fixed_def) {				\
110 		.clkdef.id = _id,					\
111 		.clkdef.name = _name,					\
112 		.clkdef.parent_names = (const char *[]){_pname},	\
113 		.clkdef.parent_cnt = 1,					\
114 		.clkdef.flags = CLK_NODE_STATIC_STRINGS,		\
115 		.mult = _mult,						\
116 		.div = _div,						\
117 	},								\
118 }
119 
120 /* Clock gate */
121 #define	GATE(_id, _name, _pname, _o, _shift)				\
122 {									\
123 	.type = IMX_CLK_GATE,						\
124 	.clk.gate = &(struct imx_clk_gate_def) {			\
125 		.clkdef.id = _id,					\
126 		.clkdef.name = _name,					\
127 		.clkdef.parent_names = (const char *[]){_pname},	\
128 		.clkdef.parent_cnt = 1,					\
129 		.clkdef.flags = CLK_NODE_STATIC_STRINGS,		\
130 		.offset = _o,						\
131 		.shift = _shift,					\
132 		.mask = 1,						\
133 	},								\
134 }
135 
136 /* Root clock gate */
137 #define	ROOT_GATE(_id, _name, _pname, _reg)				\
138 {									\
139 	.type = IMX_CLK_GATE,						\
140 	.clk.gate = &(struct imx_clk_gate_def) {			\
141 		.clkdef.id = _id,					\
142 		.clkdef.name = _name,					\
143 		.clkdef.parent_names = (const char *[]){_pname},	\
144 		.clkdef.parent_cnt = 1,					\
145 		.clkdef.flags = CLK_NODE_STATIC_STRINGS,		\
146 		.offset = _reg,						\
147 		.shift = 0,						\
148 		.mask = 3,						\
149 	},								\
150 }
151 
152 /* Composite clock with GATE, MUX, PRE_DIV, and POST_DIV */
153 #define COMPOSITE(_id, _name, _pn, _o, _flags)				\
154 {									\
155 	.type = IMX_CLK_COMPOSITE,					\
156 	.clk.composite = &(struct imx_clk_composite_def) {		\
157 		.clkdef.id = _id,					\
158 		.clkdef.name = _name,					\
159 		.clkdef.parent_names = _pn,				\
160 		.clkdef.parent_cnt = nitems(_pn),			\
161 		.clkdef.flags = CLK_NODE_STATIC_STRINGS,		\
162 		.offset = _o,						\
163 		.flags = _flags,					\
164 	},								\
165 }
166 
167 /* SSCG PLL */
168 #define SSCG_PLL(_id, _name, _pn, _o)					\
169 {									\
170 	.type = IMX_CLK_SSCG_PLL,					\
171 	.clk.composite = &(struct imx_clk_composite_def) {		\
172 		.clkdef.id = _id,					\
173 		.clkdef.name = _name,					\
174 		.clkdef.parent_names = _pn,				\
175 		.clkdef.parent_cnt = nitems(_pn),			\
176 		.clkdef.flags = CLK_NODE_STATIC_STRINGS,		\
177 		.offset = _o,						\
178 	},								\
179 }
180 
181 /* Fractional PLL */
182 #define FRAC_PLL(_id, _name, _pname, _o)				\
183 {									\
184 	.type = IMX_CLK_FRAC_PLL,					\
185 	.clk.frac_pll = &(struct imx_clk_frac_pll_def) {		\
186 		.clkdef.id = _id,					\
187 		.clkdef.name = _name,					\
188 		.clkdef.parent_names = (const char *[]){_pname},	\
189 		.clkdef.parent_cnt = 1,					\
190 		.clkdef.flags = CLK_NODE_STATIC_STRINGS,		\
191 		.offset = _o,						\
192 	},								\
193 }
194 
195 #define DIV(_id, _name, _pname, _o, _shift, _width)			\
196 {									\
197 	.type = IMX_CLK_DIV,						\
198 	.clk.div = &(struct clk_div_def) {				\
199 		.clkdef.id = _id,					\
200 		.clkdef.name = _name,					\
201 		.clkdef.parent_names = (const char *[]){_pname},	\
202 		.clkdef.parent_cnt = 1,					\
203 		.clkdef.flags = CLK_NODE_STATIC_STRINGS,		\
204 		.offset = _o,						\
205 		.i_shift = _shift,					\
206 		.i_width = _width,					\
207 	},								\
208 }
209 
210 #endif
211