rk_cru.h revision 1.11 1 1.11 ryo /* $NetBSD: rk_cru.h,v 1.11 2022/08/23 05:39:06 ryo Exp $ */
2 1.1 jmcneill
3 1.1 jmcneill /*-
4 1.1 jmcneill * Copyright (c) 2018 Jared McNeill <jmcneill (at) invisible.ca>
5 1.1 jmcneill * All rights reserved.
6 1.1 jmcneill *
7 1.1 jmcneill * Redistribution and use in source and binary forms, with or without
8 1.1 jmcneill * modification, are permitted provided that the following conditions
9 1.1 jmcneill * are met:
10 1.1 jmcneill * 1. Redistributions of source code must retain the above copyright
11 1.1 jmcneill * notice, this list of conditions and the following disclaimer.
12 1.1 jmcneill * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 jmcneill * notice, this list of conditions and the following disclaimer in the
14 1.1 jmcneill * documentation and/or other materials provided with the distribution.
15 1.1 jmcneill *
16 1.1 jmcneill * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 1.1 jmcneill * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 1.1 jmcneill * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 1.1 jmcneill * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 1.1 jmcneill * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 1.1 jmcneill * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 1.1 jmcneill * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 1.1 jmcneill * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 1.1 jmcneill * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 1.1 jmcneill * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 1.1 jmcneill * SUCH DAMAGE.
27 1.1 jmcneill */
28 1.1 jmcneill
29 1.1 jmcneill #ifndef _ARM_RK_CRU_H
30 1.1 jmcneill #define _ARM_RK_CRU_H
31 1.1 jmcneill
32 1.1 jmcneill #include <dev/clk/clk_backend.h>
33 1.2 jmcneill #include <dev/fdt/syscon.h>
34 1.1 jmcneill
35 1.1 jmcneill struct rk_cru_softc;
36 1.1 jmcneill struct rk_cru_clk;
37 1.1 jmcneill
38 1.1 jmcneill /*
39 1.1 jmcneill * Clocks
40 1.1 jmcneill */
41 1.1 jmcneill
42 1.1 jmcneill enum rk_cru_clktype {
43 1.1 jmcneill RK_CRU_UNKNOWN,
44 1.1 jmcneill RK_CRU_PLL,
45 1.1 jmcneill RK_CRU_ARM,
46 1.1 jmcneill RK_CRU_COMPOSITE,
47 1.1 jmcneill RK_CRU_GATE,
48 1.1 jmcneill RK_CRU_MUX,
49 1.1 jmcneill };
50 1.1 jmcneill
51 1.1 jmcneill /* PLL clocks */
52 1.1 jmcneill
53 1.1 jmcneill struct rk_cru_pll_rate {
54 1.11 ryo u_int rate;
55 1.11 ryo union {
56 1.11 ryo struct { /* RK3328,3399 */
57 1.11 ryo u_int refdiv;
58 1.11 ryo u_int fbdiv;
59 1.11 ryo u_int postdiv1;
60 1.11 ryo u_int postdiv2;
61 1.11 ryo u_int dsmpd;
62 1.11 ryo u_int fracdiv;
63 1.11 ryo };
64 1.11 ryo struct { /* RK3588 */
65 1.11 ryo u_int p;
66 1.11 ryo u_int m;
67 1.11 ryo u_int s;
68 1.11 ryo u_int k;
69 1.11 ryo };
70 1.11 ryo };
71 1.1 jmcneill };
72 1.1 jmcneill
73 1.1 jmcneill #define RK_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _fracdiv) \
74 1.1 jmcneill { \
75 1.1 jmcneill .rate = (_rate), \
76 1.1 jmcneill .refdiv = (_refdiv), \
77 1.1 jmcneill .fbdiv = (_fbdiv), \
78 1.1 jmcneill .postdiv1 = (_postdiv1), \
79 1.1 jmcneill .postdiv2 = (_postdiv2), \
80 1.1 jmcneill .dsmpd = (_dsmpd), \
81 1.1 jmcneill .fracdiv = (_fracdiv), \
82 1.1 jmcneill }
83 1.1 jmcneill
84 1.11 ryo #define RK3588_PLL_RATE(_rate, _p, _m, _s, _k) \
85 1.11 ryo { \
86 1.11 ryo .rate = (_rate), \
87 1.11 ryo .p = (_p), \
88 1.11 ryo .m = (_m), \
89 1.11 ryo .s = (_s), \
90 1.11 ryo .k = (_k), \
91 1.11 ryo }
92 1.11 ryo
93 1.1 jmcneill struct rk_cru_pll {
94 1.1 jmcneill bus_size_t con_base;
95 1.1 jmcneill bus_size_t mode_reg;
96 1.1 jmcneill uint32_t mode_mask;
97 1.1 jmcneill uint32_t lock_mask;
98 1.1 jmcneill const struct rk_cru_pll_rate *rates;
99 1.1 jmcneill u_int nrates;
100 1.3 jmcneill const char **parents;
101 1.3 jmcneill u_int nparents;
102 1.8 jmcneill u_int flags;
103 1.8 jmcneill #define RK_PLL_RK3288 0x01
104 1.11 ryo #define RK_PLL_RK3588 0x02
105 1.1 jmcneill };
106 1.1 jmcneill
107 1.1 jmcneill u_int rk_cru_pll_get_rate(struct rk_cru_softc *, struct rk_cru_clk *);
108 1.1 jmcneill int rk_cru_pll_set_rate(struct rk_cru_softc *, struct rk_cru_clk *, u_int);
109 1.1 jmcneill const char *rk_cru_pll_get_parent(struct rk_cru_softc *, struct rk_cru_clk *);
110 1.1 jmcneill
111 1.10 ryo #define RK_PLL_FLAGS(_id, _name, _parents, _con_base, _mode_reg, _mode_mask, _lock_mask, _rates, _flags) \
112 1.1 jmcneill { \
113 1.1 jmcneill .id = (_id), \
114 1.1 jmcneill .type = RK_CRU_PLL, \
115 1.1 jmcneill .base.name = (_name), \
116 1.1 jmcneill .base.flags = 0, \
117 1.3 jmcneill .u.pll.parents = (_parents), \
118 1.3 jmcneill .u.pll.nparents = __arraycount(_parents), \
119 1.1 jmcneill .u.pll.con_base = (_con_base), \
120 1.1 jmcneill .u.pll.mode_reg = (_mode_reg), \
121 1.1 jmcneill .u.pll.mode_mask = (_mode_mask), \
122 1.1 jmcneill .u.pll.lock_mask = (_lock_mask), \
123 1.1 jmcneill .u.pll.rates = (_rates), \
124 1.1 jmcneill .u.pll.nrates = __arraycount(_rates), \
125 1.10 ryo .u.pll.flags = _flags, \
126 1.8 jmcneill .get_rate = rk_cru_pll_get_rate, \
127 1.8 jmcneill .set_rate = rk_cru_pll_set_rate, \
128 1.8 jmcneill .get_parent = rk_cru_pll_get_parent, \
129 1.8 jmcneill }
130 1.8 jmcneill
131 1.10 ryo #define RK_PLL(_id, _name, _parents, _con_base, _mode_reg, _mode_mask, _lock_mask, _rates) \
132 1.10 ryo RK_PLL_FLAGS(_id, _name, _parents, _con_base, _mode_reg, _mode_mask, _lock_mask, _rates, 0)
133 1.10 ryo
134 1.8 jmcneill #define RK3288_PLL(_id, _name, _parents, _con_base, _mode_reg, _mode_mask, _lock_mask, _rates) \
135 1.10 ryo RK_PLL_FLAGS(_id, _name, _parents, _con_base, _mode_reg, _mode_mask, _lock_mask, _rates, RK_PLL_RK3288)
136 1.1 jmcneill
137 1.11 ryo #define RK3588_PLL(_id, _name, _parents, _con_base, _mode_reg, _mode_mask, _lock_mask, _rates) \
138 1.11 ryo RK_PLL_FLAGS(_id, _name, _parents, _con_base, _mode_reg, _mode_mask, _lock_mask, _rates, RK_PLL_RK3588)
139 1.11 ryo
140 1.1 jmcneill /* ARM clocks */
141 1.1 jmcneill
142 1.1 jmcneill struct rk_cru_arm_rate {
143 1.1 jmcneill u_int rate;
144 1.1 jmcneill u_int div;
145 1.1 jmcneill };
146 1.1 jmcneill
147 1.1 jmcneill #define RK_ARM_RATE(_rate, _div) \
148 1.1 jmcneill { \
149 1.1 jmcneill .rate = (_rate), \
150 1.1 jmcneill .div = (_div), \
151 1.1 jmcneill }
152 1.1 jmcneill
153 1.9 ryo struct rk_regmaskval {
154 1.9 ryo bus_size_t reg;
155 1.9 ryo uint32_t mask;
156 1.9 ryo uint32_t val;
157 1.9 ryo };
158 1.9 ryo
159 1.4 jmcneill struct rk_cru_cpu_rate {
160 1.9 ryo u_int rate;
161 1.11 ryo struct rk_regmaskval divs[4];
162 1.11 ryo struct rk_regmaskval pre_muxs[3];
163 1.11 ryo struct rk_regmaskval post_muxs[3];
164 1.4 jmcneill };
165 1.4 jmcneill
166 1.10 ryo struct rk_regmask {
167 1.10 ryo bus_size_t reg;
168 1.10 ryo uint32_t mask;
169 1.10 ryo };
170 1.10 ryo
171 1.1 jmcneill struct rk_cru_arm {
172 1.10 ryo bus_size_t mux_reg;
173 1.1 jmcneill uint32_t mux_mask;
174 1.1 jmcneill u_int mux_main;
175 1.1 jmcneill u_int mux_alt;
176 1.11 ryo struct rk_regmask divs[4];
177 1.1 jmcneill const char **parents;
178 1.1 jmcneill u_int nparents;
179 1.1 jmcneill const struct rk_cru_arm_rate *rates;
180 1.4 jmcneill const struct rk_cru_cpu_rate *cpurates;
181 1.1 jmcneill u_int nrates;
182 1.1 jmcneill };
183 1.1 jmcneill
184 1.1 jmcneill u_int rk_cru_arm_get_rate(struct rk_cru_softc *, struct rk_cru_clk *);
185 1.1 jmcneill int rk_cru_arm_set_rate(struct rk_cru_softc *, struct rk_cru_clk *, u_int);
186 1.4 jmcneill int rk_cru_arm_set_rate(struct rk_cru_softc *, struct rk_cru_clk *, u_int);
187 1.1 jmcneill const char *rk_cru_arm_get_parent(struct rk_cru_softc *, struct rk_cru_clk *);
188 1.1 jmcneill int rk_cru_arm_set_parent(struct rk_cru_softc *, struct rk_cru_clk *, const char *);
189 1.1 jmcneill
190 1.1 jmcneill #define RK_ARM(_id, _name, _parents, _reg, _mux_mask, _mux_main, _mux_alt, _div_mask, _rates) \
191 1.1 jmcneill { \
192 1.1 jmcneill .id = (_id), \
193 1.1 jmcneill .type = RK_CRU_ARM, \
194 1.1 jmcneill .base.name = (_name), \
195 1.1 jmcneill .base.flags = 0, \
196 1.1 jmcneill .u.arm.parents = (_parents), \
197 1.1 jmcneill .u.arm.nparents = __arraycount(_parents), \
198 1.10 ryo .u.arm.mux_reg = (_reg), \
199 1.1 jmcneill .u.arm.mux_mask = (_mux_mask), \
200 1.1 jmcneill .u.arm.mux_main = (_mux_main), \
201 1.1 jmcneill .u.arm.mux_alt = (_mux_alt), \
202 1.10 ryo .u.arm.divs[0].reg = (_reg), \
203 1.10 ryo .u.arm.divs[0].mask = (_div_mask), \
204 1.1 jmcneill .u.arm.rates = (_rates), \
205 1.1 jmcneill .u.arm.nrates = __arraycount(_rates), \
206 1.1 jmcneill .get_rate = rk_cru_arm_get_rate, \
207 1.1 jmcneill .set_rate = rk_cru_arm_set_rate, \
208 1.1 jmcneill .get_parent = rk_cru_arm_get_parent, \
209 1.1 jmcneill .set_parent = rk_cru_arm_set_parent, \
210 1.1 jmcneill }
211 1.1 jmcneill
212 1.10 ryo #define _RK_CPU_COMMON_INITIALIZER(_id, _name, _parents, \
213 1.10 ryo _mux_reg, _mux_mask, _mux_main, _mux_alt, _cpurates) \
214 1.10 ryo .id = (_id), \
215 1.10 ryo .type = RK_CRU_ARM, \
216 1.10 ryo .base.name = (_name), \
217 1.10 ryo .base.flags = 0, \
218 1.10 ryo .u.arm.parents = (_parents), \
219 1.10 ryo .u.arm.nparents = __arraycount(_parents), \
220 1.10 ryo .u.arm.mux_reg = (_mux_reg), \
221 1.10 ryo .u.arm.mux_mask = (_mux_mask), \
222 1.10 ryo .u.arm.mux_main = (_mux_main), \
223 1.10 ryo .u.arm.mux_alt = (_mux_alt), \
224 1.10 ryo .u.arm.cpurates = (_cpurates), \
225 1.10 ryo .u.arm.nrates = __arraycount(_cpurates), \
226 1.10 ryo .get_rate = rk_cru_arm_get_rate, \
227 1.10 ryo .set_rate = rk_cru_arm_set_rate, \
228 1.10 ryo .get_parent = rk_cru_arm_get_parent, \
229 1.10 ryo .set_parent = rk_cru_arm_set_parent
230 1.10 ryo
231 1.10 ryo #define RK_CPU(_id, _name, _parents, _mux_reg, _mux_mask, _mux_main, _mux_alt, \
232 1.10 ryo _div_reg, _div_mask, _cpurates) \
233 1.10 ryo { \
234 1.10 ryo _RK_CPU_COMMON_INITIALIZER(_id, _name, _parents, \
235 1.10 ryo _mux_reg, _mux_mask, _mux_main, _mux_alt,_cpurates),\
236 1.10 ryo .u.arm.divs[0].reg = (_div_reg), \
237 1.10 ryo .u.arm.divs[0].mask = (_div_mask), \
238 1.4 jmcneill }
239 1.4 jmcneill
240 1.11 ryo #define RK_CPU_CORE2(_id, _name, _parents, \
241 1.11 ryo _mux_reg, _mux_mask, _mux_main, _mux_alt, \
242 1.11 ryo _div0_reg, _div0_mask, \
243 1.11 ryo _div1_reg, _div1_mask, \
244 1.11 ryo _cpurates) \
245 1.11 ryo { \
246 1.11 ryo _RK_CPU_COMMON_INITIALIZER(_id, _name, _parents, \
247 1.11 ryo _mux_reg, _mux_mask, _mux_main, _mux_alt,_cpurates),\
248 1.11 ryo .u.arm.divs[0].reg = (_div0_reg), \
249 1.11 ryo .u.arm.divs[0].mask = (_div0_mask), \
250 1.11 ryo .u.arm.divs[1].reg = (_div1_reg), \
251 1.11 ryo .u.arm.divs[1].mask = (_div1_mask), \
252 1.11 ryo }
253 1.11 ryo
254 1.11 ryo #define RK_CPU_CORE4(_id, _name, _parents, \
255 1.11 ryo _mux_reg, _mux_mask, _mux_main, _mux_alt, \
256 1.11 ryo _div0_reg, _div0_mask, \
257 1.11 ryo _div1_reg, _div1_mask, \
258 1.11 ryo _div2_reg, _div2_mask, \
259 1.11 ryo _div3_reg, _div3_mask, \
260 1.11 ryo _cpurates) \
261 1.11 ryo { \
262 1.11 ryo _RK_CPU_COMMON_INITIALIZER(_id, _name, _parents, \
263 1.11 ryo _mux_reg, _mux_mask, _mux_main, _mux_alt,_cpurates),\
264 1.11 ryo .u.arm.divs[0].reg = (_div0_reg), \
265 1.11 ryo .u.arm.divs[0].mask = (_div0_mask), \
266 1.11 ryo .u.arm.divs[1].reg = (_div1_reg), \
267 1.11 ryo .u.arm.divs[1].mask = (_div1_mask), \
268 1.11 ryo .u.arm.divs[2].reg = (_div2_reg), \
269 1.11 ryo .u.arm.divs[2].mask = (_div2_mask), \
270 1.11 ryo .u.arm.divs[3].reg = (_div3_reg), \
271 1.11 ryo .u.arm.divs[3].mask = (_div3_mask), \
272 1.11 ryo }
273 1.11 ryo
274 1.1 jmcneill /* Composite clocks */
275 1.1 jmcneill
276 1.1 jmcneill struct rk_cru_composite {
277 1.1 jmcneill bus_size_t muxdiv_reg;
278 1.1 jmcneill uint32_t mux_mask;
279 1.1 jmcneill uint32_t div_mask;
280 1.1 jmcneill bus_size_t gate_reg;
281 1.1 jmcneill uint32_t gate_mask;
282 1.7 jmcneill bus_size_t frac_reg;
283 1.1 jmcneill const char **parents;
284 1.1 jmcneill u_int nparents;
285 1.1 jmcneill u_int flags;
286 1.1 jmcneill #define RK_COMPOSITE_ROUND_DOWN 0x01
287 1.6 jmcneill #define RK_COMPOSITE_SET_RATE_PARENT 0x02
288 1.7 jmcneill #define RK_COMPOSITE_FRACDIV 0x04
289 1.8 jmcneill #define RK_COMPOSITE_POW2 0x08
290 1.11 ryo #define RK_COMPOSITE_HALFDIV 0x10
291 1.1 jmcneill };
292 1.1 jmcneill
293 1.1 jmcneill int rk_cru_composite_enable(struct rk_cru_softc *, struct rk_cru_clk *, int);
294 1.1 jmcneill u_int rk_cru_composite_get_rate(struct rk_cru_softc *, struct rk_cru_clk *);
295 1.1 jmcneill int rk_cru_composite_set_rate(struct rk_cru_softc *, struct rk_cru_clk *, u_int);
296 1.1 jmcneill const char *rk_cru_composite_get_parent(struct rk_cru_softc *, struct rk_cru_clk *);
297 1.1 jmcneill int rk_cru_composite_set_parent(struct rk_cru_softc *, struct rk_cru_clk *, const char *);
298 1.1 jmcneill
299 1.7 jmcneill #define _RK_COMPOSITE_INIT(_id, _name, _parents, _muxdiv_reg, _mux_mask, _div_mask, _gate_reg, _gate_mask, _frac_reg, _flags) \
300 1.1 jmcneill { \
301 1.1 jmcneill .id = (_id), \
302 1.1 jmcneill .type = RK_CRU_COMPOSITE, \
303 1.1 jmcneill .base.name = (_name), \
304 1.1 jmcneill .base.flags = 0, \
305 1.1 jmcneill .u.composite.parents = (_parents), \
306 1.1 jmcneill .u.composite.nparents = __arraycount(_parents), \
307 1.1 jmcneill .u.composite.muxdiv_reg = (_muxdiv_reg), \
308 1.1 jmcneill .u.composite.mux_mask = (_mux_mask), \
309 1.1 jmcneill .u.composite.div_mask = (_div_mask), \
310 1.1 jmcneill .u.composite.gate_reg = (_gate_reg), \
311 1.1 jmcneill .u.composite.gate_mask = (_gate_mask), \
312 1.7 jmcneill .u.composite.frac_reg = (_frac_reg), \
313 1.1 jmcneill .u.composite.flags = (_flags), \
314 1.1 jmcneill .enable = rk_cru_composite_enable, \
315 1.1 jmcneill .get_rate = rk_cru_composite_get_rate, \
316 1.1 jmcneill .set_rate = rk_cru_composite_set_rate, \
317 1.1 jmcneill .get_parent = rk_cru_composite_get_parent, \
318 1.1 jmcneill .set_parent = rk_cru_composite_set_parent, \
319 1.1 jmcneill }
320 1.1 jmcneill
321 1.7 jmcneill #define RK_COMPOSITE(_id, _name, _parents, _muxdiv_reg, _mux_mask, _div_mask, _gate_reg, _gate_mask, _flags) \
322 1.7 jmcneill _RK_COMPOSITE_INIT(_id, _name, _parents, _muxdiv_reg, _mux_mask, _div_mask, _gate_reg, _gate_mask, 0, _flags)
323 1.7 jmcneill
324 1.11 ryo #define RK_COMPOSITE_HALF(_id, _name, _parents, _muxdiv_reg, _mux_mask, _div_mask, _gate_reg, _gate_mask, _flags) \
325 1.11 ryo _RK_COMPOSITE_INIT(_id, _name, _parents, _muxdiv_reg, _mux_mask, _div_mask, _gate_reg, _gate_mask, 0, (_flags) | RK_COMPOSITE_HALFDIV)
326 1.11 ryo
327 1.3 jmcneill #define RK_COMPOSITE_NOMUX(_id, _name, _parent, _div_reg, _div_mask, _gate_reg, _gate_mask, _flags) \
328 1.7 jmcneill _RK_COMPOSITE_INIT(_id, _name, (const char *[]){ _parent }, _div_reg, 0, _div_mask, _gate_reg, _gate_mask, 0, _flags)
329 1.3 jmcneill
330 1.11 ryo #define RK_COMPOSITE_NODIV(_id, _name, _parents, _muxdiv_reg, _mux_mask, _gate_reg, _gate_mask, _flags) \
331 1.11 ryo _RK_COMPOSITE_INIT(_id, _name, _parents, _muxdiv_reg, _mux_mask, 0, _gate_reg, _gate_mask, 0, _flags)
332 1.11 ryo
333 1.3 jmcneill #define RK_COMPOSITE_NOGATE(_id, _name, _parents, _muxdiv_reg, _mux_mask, _div_mask, _flags) \
334 1.7 jmcneill _RK_COMPOSITE_INIT(_id, _name, _parents, _muxdiv_reg, _mux_mask, _div_mask, 0, 0, 0, _flags)
335 1.7 jmcneill
336 1.7 jmcneill #define RK_COMPOSITE_FRAC(_id, _name, _parent, _frac_reg, _flags) \
337 1.7 jmcneill _RK_COMPOSITE_INIT(_id, _name, (const char *[]){ _parent }, 0, 0, 0, 0, 0, _frac_reg, (_flags) | RK_COMPOSITE_FRACDIV)
338 1.3 jmcneill
339 1.3 jmcneill #define RK_DIV(_id, _name, _parent, _div_reg, _div_mask, _flags) \
340 1.7 jmcneill _RK_COMPOSITE_INIT(_id, _name, (const char *[]){ _parent }, _div_reg, 0, _div_mask, 0, 0, 0, _flags)
341 1.3 jmcneill
342 1.1 jmcneill /* Gate clocks */
343 1.1 jmcneill
344 1.1 jmcneill struct rk_cru_gate {
345 1.1 jmcneill bus_size_t reg;
346 1.1 jmcneill uint32_t mask;
347 1.1 jmcneill const char *parent;
348 1.1 jmcneill };
349 1.1 jmcneill
350 1.1 jmcneill int rk_cru_gate_enable(struct rk_cru_softc *,
351 1.1 jmcneill struct rk_cru_clk *, int);
352 1.1 jmcneill const char *rk_cru_gate_get_parent(struct rk_cru_softc *,
353 1.1 jmcneill struct rk_cru_clk *);
354 1.1 jmcneill
355 1.1 jmcneill #define RK_GATE(_id, _name, _pname, _reg, _bit) \
356 1.1 jmcneill { \
357 1.1 jmcneill .id = (_id), \
358 1.1 jmcneill .type = RK_CRU_GATE, \
359 1.1 jmcneill .base.name = (_name), \
360 1.1 jmcneill .base.flags = CLK_SET_RATE_PARENT, \
361 1.1 jmcneill .u.gate.parent = (_pname), \
362 1.1 jmcneill .u.gate.reg = (_reg), \
363 1.1 jmcneill .u.gate.mask = __BIT(_bit), \
364 1.1 jmcneill .enable = rk_cru_gate_enable, \
365 1.1 jmcneill .get_parent = rk_cru_gate_get_parent, \
366 1.1 jmcneill }
367 1.1 jmcneill
368 1.5 tnn #define RK_SECURE_GATE(_id, _name, _pname) \
369 1.5 tnn { \
370 1.5 tnn .id = (_id), \
371 1.5 tnn .type = RK_CRU_GATE, \
372 1.5 tnn .base.name = (_name), \
373 1.5 tnn .u.gate.parent = (_pname), \
374 1.5 tnn .get_parent = rk_cru_gate_get_parent, \
375 1.5 tnn }
376 1.5 tnn
377 1.1 jmcneill /* Mux clocks */
378 1.1 jmcneill
379 1.1 jmcneill struct rk_cru_mux {
380 1.1 jmcneill bus_size_t reg;
381 1.1 jmcneill uint32_t mask;
382 1.1 jmcneill const char **parents;
383 1.1 jmcneill u_int nparents;
384 1.1 jmcneill u_int flags;
385 1.1 jmcneill #define RK_MUX_GRF 0x01
386 1.1 jmcneill };
387 1.1 jmcneill
388 1.1 jmcneill const char *rk_cru_mux_get_parent(struct rk_cru_softc *, struct rk_cru_clk *);
389 1.1 jmcneill int rk_cru_mux_set_parent(struct rk_cru_softc *, struct rk_cru_clk *, const char *);
390 1.1 jmcneill
391 1.1 jmcneill #define RK_MUX_FLAGS(_id, _name, _parents, _reg, _mask, _flags) \
392 1.1 jmcneill { \
393 1.1 jmcneill .id = (_id), \
394 1.1 jmcneill .type = RK_CRU_MUX, \
395 1.1 jmcneill .base.name = (_name), \
396 1.1 jmcneill .base.flags = CLK_SET_RATE_PARENT, \
397 1.1 jmcneill .u.mux.parents = (_parents), \
398 1.1 jmcneill .u.mux.nparents = __arraycount(_parents), \
399 1.1 jmcneill .u.mux.reg = (_reg), \
400 1.1 jmcneill .u.mux.mask = (_mask), \
401 1.1 jmcneill .u.mux.flags = (_flags), \
402 1.1 jmcneill .set_parent = rk_cru_mux_set_parent, \
403 1.1 jmcneill .get_parent = rk_cru_mux_get_parent, \
404 1.1 jmcneill }
405 1.1 jmcneill #define RK_MUX(_id, _name, _parents, _reg, _mask) \
406 1.1 jmcneill RK_MUX_FLAGS(_id, _name, _parents, _reg, _mask, 0)
407 1.1 jmcneill #define RK_MUXGRF(_id, _name, _parents, _reg, _mask) \
408 1.1 jmcneill RK_MUX_FLAGS(_id, _name, _parents, _reg, _mask, RK_MUX_GRF)
409 1.1 jmcneill
410 1.1 jmcneill /*
411 1.1 jmcneill * Rockchip clock definition
412 1.1 jmcneill */
413 1.1 jmcneill
414 1.1 jmcneill struct rk_cru_clk {
415 1.1 jmcneill struct clk base;
416 1.1 jmcneill u_int id;
417 1.1 jmcneill enum rk_cru_clktype type;
418 1.1 jmcneill union {
419 1.1 jmcneill struct rk_cru_pll pll;
420 1.1 jmcneill struct rk_cru_arm arm;
421 1.1 jmcneill struct rk_cru_composite composite;
422 1.1 jmcneill struct rk_cru_gate gate;
423 1.1 jmcneill struct rk_cru_mux mux;
424 1.1 jmcneill } u;
425 1.1 jmcneill
426 1.1 jmcneill int (*enable)(struct rk_cru_softc *,
427 1.1 jmcneill struct rk_cru_clk *, int);
428 1.1 jmcneill u_int (*get_rate)(struct rk_cru_softc *,
429 1.1 jmcneill struct rk_cru_clk *);
430 1.1 jmcneill int (*set_rate)(struct rk_cru_softc *,
431 1.1 jmcneill struct rk_cru_clk *, u_int);
432 1.1 jmcneill u_int (*round_rate)(struct rk_cru_softc *,
433 1.1 jmcneill struct rk_cru_clk *, u_int);
434 1.1 jmcneill const char * (*get_parent)(struct rk_cru_softc *,
435 1.1 jmcneill struct rk_cru_clk *);
436 1.1 jmcneill int (*set_parent)(struct rk_cru_softc *,
437 1.1 jmcneill struct rk_cru_clk *,
438 1.1 jmcneill const char *);
439 1.1 jmcneill };
440 1.1 jmcneill
441 1.1 jmcneill /*
442 1.1 jmcneill * Driver state
443 1.1 jmcneill */
444 1.1 jmcneill
445 1.1 jmcneill struct rk_cru_softc {
446 1.1 jmcneill device_t sc_dev;
447 1.1 jmcneill int sc_phandle;
448 1.1 jmcneill bus_space_tag_t sc_bst;
449 1.1 jmcneill bus_space_handle_t sc_bsh;
450 1.2 jmcneill struct syscon *sc_grf;
451 1.1 jmcneill
452 1.1 jmcneill struct clk_domain sc_clkdom;
453 1.1 jmcneill
454 1.1 jmcneill struct rk_cru_clk *sc_clks;
455 1.1 jmcneill u_int sc_nclks;
456 1.3 jmcneill
457 1.8 jmcneill bus_size_t sc_grf_soc_status; /* for PLL lock */
458 1.3 jmcneill bus_size_t sc_softrst_base;
459 1.1 jmcneill };
460 1.1 jmcneill
461 1.1 jmcneill int rk_cru_attach(struct rk_cru_softc *);
462 1.1 jmcneill struct rk_cru_clk *rk_cru_clock_find(struct rk_cru_softc *,
463 1.1 jmcneill const char *);
464 1.1 jmcneill void rk_cru_print(struct rk_cru_softc *);
465 1.1 jmcneill
466 1.1 jmcneill #define CRU_READ(sc, reg) \
467 1.1 jmcneill bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
468 1.1 jmcneill #define CRU_WRITE(sc, reg, val) \
469 1.1 jmcneill bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
470 1.1 jmcneill
471 1.2 jmcneill #define HAS_GRF(sc) ((sc)->sc_grf != NULL)
472 1.1 jmcneill
473 1.1 jmcneill #endif /* _ARM_RK_CRU_H */
474