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