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