Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/dev/clk/rockchip/rk_cru.h
39537 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2018 Emmanuel Vadot <[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 ``AS IS'' AND ANY EXPRESS OR
16
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
20
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
22
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
* 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 __RK_CRU_H__
29
#define __RK_CRU_H__
30
31
#include <dev/clk/clk.h>
32
#include <dev/clk/clk_div.h>
33
#include <dev/clk/clk_gate.h>
34
#include <dev/clk/clk_fixed.h>
35
#include <dev/clk/clk_link.h>
36
37
#include <dev/clk/rockchip/rk_clk_armclk.h>
38
#include <dev/clk/rockchip/rk_clk_composite.h>
39
#include <dev/clk/rockchip/rk_clk_fract.h>
40
#include <dev/clk/rockchip/rk_clk_gate.h>
41
#include <dev/clk/rockchip/rk_clk_mux.h>
42
#include <dev/clk/rockchip/rk_clk_pll.h>
43
44
/* Macro for defining various types of clocks. */
45
46
/* Parent list */
47
#define PLIST(_name) static const char *_name[]
48
49
/* Pure gate */
50
#define GATE(_idx, _clkname, _pname, _o, _s) \
51
{ \
52
.id = _idx, \
53
.name = _clkname, \
54
.parent_name = _pname, \
55
.offset = CRU_CLKGATE_CON(_o), \
56
.shift = _s, \
57
}
58
59
/* Fixed rate clock. */
60
#define FRATE(_id, _name, _freq) \
61
{ \
62
.type = RK_CLK_FIXED, \
63
.clk.fixed = &(struct clk_fixed_def) { \
64
.clkdef.id = _id, \
65
.clkdef.name = _name, \
66
.clkdef.parent_names = NULL, \
67
.clkdef.parent_cnt = 0, \
68
.clkdef.flags = CLK_NODE_STATIC_STRINGS, \
69
.freq = _freq, \
70
}, \
71
}
72
73
/* Fixed factor multipier/divider. */
74
#define FFACT(_id, _name, _pname, _mult, _div) \
75
{ \
76
.type = RK_CLK_FIXED, \
77
.clk.fixed = &(struct clk_fixed_def) { \
78
.clkdef.id = _id, \
79
.clkdef.name = _name, \
80
.clkdef.parent_names = (const char *[]){_pname}, \
81
.clkdef.parent_cnt = 1, \
82
.clkdef.flags = CLK_NODE_STATIC_STRINGS, \
83
.mult = _mult, \
84
.div = _div, \
85
}, \
86
}
87
88
/* Linked clock. */
89
#define LINK(_name) \
90
{ \
91
.type = RK_CLK_LINK, \
92
.clk.link = &(struct clk_link_def) { \
93
.clkdef.id = 0, \
94
.clkdef.name = _name, \
95
.clkdef.parent_names = NULL, \
96
.clkdef.parent_cnt = 0, \
97
.clkdef.flags = CLK_NODE_STATIC_STRINGS, \
98
}, \
99
}
100
101
/* Complex clock fo ARM cores. */
102
#define ARMDIV(_id, _name, _pn, _r, _o, _ds, _dw, _ms, _mw, _mp, _ap) \
103
{ \
104
.type = RK_CLK_ARMCLK, \
105
.clk.armclk = &(struct rk_clk_armclk_def) { \
106
.clkdef.id = _id, \
107
.clkdef.name = _name, \
108
.clkdef.parent_names = _pn, \
109
.clkdef.parent_cnt = nitems(_pn), \
110
.clkdef.flags = CLK_NODE_STATIC_STRINGS, \
111
.muxdiv_offset = CRU_CLKSEL_CON(_o), \
112
.mux_shift = _ms, \
113
.mux_width = _mw, \
114
.div_shift = _ds, \
115
.div_width = _dw, \
116
.main_parent = _mp, \
117
.alt_parent = _ap, \
118
.rates = _r, \
119
.nrates = nitems(_r), \
120
}, \
121
}
122
123
/* Fractional rate multipier/divider. */
124
#define FRACT(_id, _name, _pname, _f, _o) \
125
{ \
126
.type = RK_CLK_FRACT, \
127
.clk.fract = &(struct rk_clk_fract_def) { \
128
.clkdef.id = _id, \
129
.clkdef.name = _name, \
130
.clkdef.parent_names = (const char *[]){_pname}, \
131
.clkdef.parent_cnt = 1, \
132
.clkdef.flags = CLK_NODE_STATIC_STRINGS, \
133
.offset = CRU_CLKSEL_CON(_o), \
134
.flags = _f, \
135
}, \
136
}
137
138
/* Full composite clock. */
139
#define COMP(_id, _name, _pnames, _f, _o, _ds, _dw, _ms, _mw) \
140
{ \
141
.type = RK_CLK_COMPOSITE, \
142
.clk.composite = &(struct rk_clk_composite_def) { \
143
.clkdef.id = _id, \
144
.clkdef.name = _name, \
145
.clkdef.parent_names = _pnames, \
146
.clkdef.parent_cnt = nitems(_pnames), \
147
.clkdef.flags = CLK_NODE_STATIC_STRINGS, \
148
.muxdiv_offset = CRU_CLKSEL_CON(_o), \
149
.mux_shift = _ms, \
150
.mux_width = _mw, \
151
.div_shift = _ds, \
152
.div_width = _dw, \
153
.flags = RK_CLK_COMPOSITE_HAVE_MUX | _f, \
154
}, \
155
}
156
157
/* Composite clock without mux (divider only). */
158
#define CDIV(_id, _name, _pname, _f, _o, _ds, _dw) \
159
{ \
160
.type = RK_CLK_COMPOSITE, \
161
.clk.composite = &(struct rk_clk_composite_def) { \
162
.clkdef.id = _id, \
163
.clkdef.name = _name, \
164
.clkdef.parent_names = (const char *[]){_pname}, \
165
.clkdef.parent_cnt = 1, \
166
.clkdef.flags = CLK_NODE_STATIC_STRINGS, \
167
.muxdiv_offset = CRU_CLKSEL_CON(_o), \
168
.div_shift = _ds, \
169
.div_width = _dw, \
170
.flags = _f, \
171
}, \
172
}
173
174
/* Complex clock without divider (multiplexer only). */
175
#define MUXRAW(_id, _name, _pn, _f, _mo, _ms, _mw) \
176
{ \
177
.type = RK_CLK_MUX, \
178
.clk.mux = &(struct rk_clk_mux_def) { \
179
.clkdef.id = _id, \
180
.clkdef.name = _name, \
181
.clkdef.parent_names = _pn, \
182
.clkdef.parent_cnt = nitems(_pn), \
183
.clkdef.flags = CLK_NODE_STATIC_STRINGS, \
184
.offset = _mo, \
185
.shift = _ms, \
186
.width = _mw, \
187
.mux_flags = _f, \
188
}, \
189
}
190
191
#define MUX(_id, _name, _pn, _f, _mo, _ms, _mw) \
192
MUXRAW(_id, _name, _pn, _f, CRU_CLKSEL_CON(_mo), _ms, _mw)
193
194
/* Complex clock without divider (multiplexer only in GRF). */
195
#define MUXGRF(_id, _name, _pn, _f, _mo, _ms, _mw) \
196
{ \
197
.type = RK_CLK_MUX, \
198
.clk.mux = &(struct rk_clk_mux_def) { \
199
.clkdef.id = _id, \
200
.clkdef.name = _name, \
201
.clkdef.parent_names = _pn, \
202
.clkdef.parent_cnt = nitems(_pn), \
203
.clkdef.flags = CLK_NODE_STATIC_STRINGS, \
204
.offset = _mo, \
205
.shift = _ms, \
206
.width = _mw, \
207
.mux_flags = RK_CLK_MUX_GRF | _f, \
208
}, \
209
}
210
211
struct rk_cru_gate {
212
const char *name;
213
const char *parent_name;
214
uint32_t id;
215
uint32_t offset;
216
uint32_t shift;
217
};
218
219
enum rk_clk_type {
220
RK_CLK_UNDEFINED = 0,
221
RK3066_CLK_PLL,
222
RK3328_CLK_PLL,
223
RK3399_CLK_PLL,
224
RK_CLK_COMPOSITE,
225
RK_CLK_FIXED,
226
RK_CLK_FRACT,
227
RK_CLK_MUX,
228
RK_CLK_ARMCLK,
229
RK_CLK_LINK,
230
};
231
232
struct rk_clk {
233
enum rk_clk_type type;
234
union {
235
struct rk_clk_pll_def *pll;
236
struct rk_clk_composite_def *composite;
237
struct rk_clk_mux_def *mux;
238
struct rk_clk_armclk_def *armclk;
239
struct clk_fixed_def *fixed;
240
struct rk_clk_fract_def *fract;
241
struct clk_link_def *link;
242
} clk;
243
};
244
245
struct rk_cru_softc {
246
device_t dev;
247
struct resource *res;
248
struct clkdom *clkdom;
249
struct mtx mtx;
250
int type;
251
uint32_t reset_offset;
252
uint32_t reset_num;
253
struct rk_cru_gate *gates;
254
int ngates;
255
struct rk_clk *clks;
256
int nclks;
257
struct rk_clk_armclk_def *armclk;
258
struct rk_clk_armclk_rates *armclk_rates;
259
int narmclk_rates;
260
};
261
262
DECLARE_CLASS(rk_cru_driver);
263
264
int rk_cru_attach(device_t dev);
265
266
#endif /* __RK_CRU_H__ */
267
268