Annotation of src/sys/arch/arm/sunxi/sunxi_ccu.h, Revision 1.6
1.6 ! jmcneill 1: /* $NetBSD: sunxi_ccu.h,v 1.5 2017/07/02 00:14:09 jmcneill Exp $ */
1.1 jmcneill 2:
3: /*-
4: * Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
5: * All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: *
16: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21: * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23: * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26: * SUCH DAMAGE.
27: */
28:
29: #ifndef _ARM_SUNXI_CCU_H
30: #define _ARM_SUNXI_CCU_H
31:
32: #include <dev/clk/clk_backend.h>
33:
34: struct sunxi_ccu_softc;
35: struct sunxi_ccu_clk;
36: struct sunxi_ccu_reset;
37:
38: /*
39: * Resets
40: */
41:
42: struct sunxi_ccu_reset {
43: bus_size_t reg;
44: uint32_t mask;
45: };
46:
47: #define SUNXI_CCU_RESET(_id, _reg, _bit) \
48: [_id] = { \
49: .reg = (_reg), \
50: .mask = __BIT(_bit), \
51: }
52:
53: /*
54: * Clocks
55: */
56:
57: enum sunxi_ccu_clktype {
58: SUNXI_CCU_UNKNOWN,
59: SUNXI_CCU_GATE,
60: SUNXI_CCU_NM,
1.2 jmcneill 61: SUNXI_CCU_NKMP,
62: SUNXI_CCU_PREDIV,
1.5 jmcneill 63: SUNXI_CCU_DIV,
1.1 jmcneill 64: };
65:
66: struct sunxi_ccu_gate {
67: bus_size_t reg;
68: uint32_t mask;
69: const char *parent;
70: };
71:
72: int sunxi_ccu_gate_enable(struct sunxi_ccu_softc *,
73: struct sunxi_ccu_clk *, int);
74: const char *sunxi_ccu_gate_get_parent(struct sunxi_ccu_softc *,
75: struct sunxi_ccu_clk *);
76:
77: #define SUNXI_CCU_GATE(_id, _name, _pname, _reg, _bit) \
78: [_id] = { \
79: .type = SUNXI_CCU_GATE, \
80: .base.name = (_name), \
81: .u.gate.parent = (_pname), \
82: .u.gate.reg = (_reg), \
83: .u.gate.mask = __BIT(_bit), \
84: .enable = sunxi_ccu_gate_enable, \
85: .get_parent = sunxi_ccu_gate_get_parent, \
86: }
87:
1.2 jmcneill 88: struct sunxi_ccu_nkmp {
89: bus_size_t reg;
90: const char *parent;
91: uint32_t n;
92: uint32_t k;
93: uint32_t m;
94: uint32_t p;
95: uint32_t lock;
96: uint32_t enable;
97: uint32_t flags;
1.3 jmcneill 98: #define SUNXI_CCU_NKMP_DIVIDE_BY_TWO __BIT(0)
1.6 ! jmcneill 99: #define SUNXI_CCU_NKMP_FACTOR_N_EXACT __BIT(1)
1.2 jmcneill 100: };
101:
102: int sunxi_ccu_nkmp_enable(struct sunxi_ccu_softc *,
103: struct sunxi_ccu_clk *, int);
104: u_int sunxi_ccu_nkmp_get_rate(struct sunxi_ccu_softc *,
105: struct sunxi_ccu_clk *);
106: int sunxi_ccu_nkmp_set_rate(struct sunxi_ccu_softc *,
107: struct sunxi_ccu_clk *, u_int);
108: const char *sunxi_ccu_nkmp_get_parent(struct sunxi_ccu_softc *,
109: struct sunxi_ccu_clk *);
110:
111: #define SUNXI_CCU_NKMP(_id, _name, _parent, _reg, _n, _k, _m, \
112: _p, _enable, _flags) \
113: [_id] = { \
114: .type = SUNXI_CCU_NKMP, \
115: .base.name = (_name), \
116: .u.nkmp.reg = (_reg), \
117: .u.nkmp.parent = (_parent), \
118: .u.nkmp.n = (_n), \
119: .u.nkmp.k = (_k), \
120: .u.nkmp.m = (_m), \
121: .u.nkmp.p = (_p), \
122: .u.nkmp.enable = (_enable), \
123: .u.nkmp.flags = (_flags), \
124: .enable = sunxi_ccu_nkmp_enable, \
125: .get_rate = sunxi_ccu_nkmp_get_rate, \
126: .set_rate = sunxi_ccu_nkmp_set_rate, \
127: .get_parent = sunxi_ccu_nkmp_get_parent, \
128: }
129:
1.1 jmcneill 130: struct sunxi_ccu_nm {
131: bus_size_t reg;
132: const char **parents;
133: u_int nparents;
134: uint32_t n;
135: uint32_t m;
136: uint32_t sel;
1.2 jmcneill 137: uint32_t enable;
1.1 jmcneill 138: uint32_t flags;
139: #define SUNXI_CCU_NM_POWER_OF_TWO __BIT(0)
1.2 jmcneill 140: #define SUNXI_CCU_NM_ROUND_DOWN __BIT(1)
1.1 jmcneill 141: };
142:
1.2 jmcneill 143: int sunxi_ccu_nm_enable(struct sunxi_ccu_softc *,
144: struct sunxi_ccu_clk *, int);
1.1 jmcneill 145: u_int sunxi_ccu_nm_get_rate(struct sunxi_ccu_softc *,
146: struct sunxi_ccu_clk *);
147: int sunxi_ccu_nm_set_rate(struct sunxi_ccu_softc *,
148: struct sunxi_ccu_clk *, u_int);
149: int sunxi_ccu_nm_set_parent(struct sunxi_ccu_softc *,
150: struct sunxi_ccu_clk *,
151: const char *);
152: const char *sunxi_ccu_nm_get_parent(struct sunxi_ccu_softc *,
153: struct sunxi_ccu_clk *);
154:
155: #define SUNXI_CCU_NM(_id, _name, _parents, _reg, _n, _m, _sel, \
1.2 jmcneill 156: _enable, _flags) \
1.1 jmcneill 157: [_id] = { \
158: .type = SUNXI_CCU_NM, \
159: .base.name = (_name), \
160: .u.nm.reg = (_reg), \
161: .u.nm.parents = (_parents), \
162: .u.nm.nparents = __arraycount(_parents), \
163: .u.nm.n = (_n), \
164: .u.nm.m = (_m), \
165: .u.nm.sel = (_sel), \
1.2 jmcneill 166: .u.nm.enable = (_enable), \
1.1 jmcneill 167: .u.nm.flags = (_flags), \
1.2 jmcneill 168: .enable = sunxi_ccu_nm_enable, \
169: .get_rate = sunxi_ccu_nm_get_rate, \
170: .set_rate = sunxi_ccu_nm_set_rate, \
1.1 jmcneill 171: .set_parent = sunxi_ccu_nm_set_parent, \
172: .get_parent = sunxi_ccu_nm_get_parent, \
173: }
174:
1.5 jmcneill 175: struct sunxi_ccu_div {
176: bus_size_t reg;
177: const char **parents;
178: u_int nparents;
179: uint32_t div;
180: uint32_t sel;
181: uint32_t flags;
182: #define SUNXI_CCU_DIV_POWER_OF_TWO __BIT(0)
183: #define SUNXI_CCU_DIV_ZERO_IS_ONE __BIT(1)
184: };
185:
186: u_int sunxi_ccu_div_get_rate(struct sunxi_ccu_softc *,
187: struct sunxi_ccu_clk *);
188: int sunxi_ccu_div_set_rate(struct sunxi_ccu_softc *,
189: struct sunxi_ccu_clk *, u_int);
190: int sunxi_ccu_div_set_parent(struct sunxi_ccu_softc *,
191: struct sunxi_ccu_clk *,
192: const char *);
193: const char *sunxi_ccu_div_get_parent(struct sunxi_ccu_softc *,
194: struct sunxi_ccu_clk *);
195:
196: #define SUNXI_CCU_DIV(_id, _name, _parents, _reg, _div, \
197: _sel, _flags) \
198: [_id] = { \
199: .type = SUNXI_CCU_DIV, \
200: .base.name = (_name), \
201: .u.div.reg = (_reg), \
202: .u.div.parents = (_parents), \
203: .u.div.nparents = __arraycount(_parents), \
204: .u.div.div = (_div), \
205: .u.div.sel = (_sel), \
206: .u.div.flags = (_flags), \
207: .get_rate = sunxi_ccu_div_get_rate, \
208: .set_rate = sunxi_ccu_div_set_rate, \
209: .set_parent = sunxi_ccu_div_set_parent, \
210: .get_parent = sunxi_ccu_div_get_parent, \
211: }
212:
1.2 jmcneill 213: struct sunxi_ccu_prediv {
214: bus_size_t reg;
215: const char **parents;
216: u_int nparents;
217: uint32_t prediv;
218: uint32_t prediv_sel;
219: uint32_t div;
220: uint32_t sel;
221: uint32_t flags;
222: #define SUNXI_CCU_PREDIV_POWER_OF_TWO __BIT(0)
1.4 jmcneill 223: #define SUNXI_CCU_PREDIV_DIVIDE_BY_TWO __BIT(1)
1.2 jmcneill 224: };
225:
226: u_int sunxi_ccu_prediv_get_rate(struct sunxi_ccu_softc *,
227: struct sunxi_ccu_clk *);
228: int sunxi_ccu_prediv_set_rate(struct sunxi_ccu_softc *,
229: struct sunxi_ccu_clk *, u_int);
230: int sunxi_ccu_prediv_set_parent(struct sunxi_ccu_softc *,
231: struct sunxi_ccu_clk *,
232: const char *);
233: const char *sunxi_ccu_prediv_get_parent(struct sunxi_ccu_softc *,
234: struct sunxi_ccu_clk *);
235:
236: #define SUNXI_CCU_PREDIV(_id, _name, _parents, _reg, _prediv, \
237: _prediv_sel, _div, _sel, _flags) \
238: [_id] = { \
239: .type = SUNXI_CCU_PREDIV, \
240: .base.name = (_name), \
241: .u.prediv.reg = (_reg), \
242: .u.prediv.parents = (_parents), \
243: .u.prediv.nparents = __arraycount(_parents), \
244: .u.prediv.prediv = (_prediv), \
245: .u.prediv.prediv_sel = (_prediv_sel), \
246: .u.prediv.div = (_div), \
247: .u.prediv.sel = (_sel), \
248: .u.prediv.flags = (_flags), \
249: .get_rate = sunxi_ccu_prediv_get_rate, \
250: .set_rate = sunxi_ccu_prediv_set_rate, \
251: .set_parent = sunxi_ccu_prediv_set_parent, \
252: .get_parent = sunxi_ccu_prediv_get_parent, \
253: }
254:
1.1 jmcneill 255: struct sunxi_ccu_clk {
256: struct clk base;
257: enum sunxi_ccu_clktype type;
258: union {
259: struct sunxi_ccu_gate gate;
260: struct sunxi_ccu_nm nm;
1.2 jmcneill 261: struct sunxi_ccu_nkmp nkmp;
262: struct sunxi_ccu_prediv prediv;
1.5 jmcneill 263: struct sunxi_ccu_div div;
1.1 jmcneill 264: } u;
265:
266: int (*enable)(struct sunxi_ccu_softc *,
267: struct sunxi_ccu_clk *, int);
268: u_int (*get_rate)(struct sunxi_ccu_softc *,
269: struct sunxi_ccu_clk *);
270: int (*set_rate)(struct sunxi_ccu_softc *,
271: struct sunxi_ccu_clk *, u_int);
272: const char * (*get_parent)(struct sunxi_ccu_softc *,
273: struct sunxi_ccu_clk *);
274: int (*set_parent)(struct sunxi_ccu_softc *,
275: struct sunxi_ccu_clk *,
276: const char *);
277: };
278:
279: struct sunxi_ccu_softc {
280: device_t sc_dev;
281: int sc_phandle;
282: bus_space_tag_t sc_bst;
283: bus_space_handle_t sc_bsh;
284:
285: struct clk_domain sc_clkdom;
286:
287: struct sunxi_ccu_reset *sc_resets;
288: u_int sc_nresets;
289:
290: struct sunxi_ccu_clk *sc_clks;
291: u_int sc_nclks;
292: };
293:
294: int sunxi_ccu_attach(struct sunxi_ccu_softc *);
295: struct sunxi_ccu_clk *sunxi_ccu_clock_find(struct sunxi_ccu_softc *,
296: const char *);
297: void sunxi_ccu_print(struct sunxi_ccu_softc *);
298:
299: #define CCU_READ(sc, reg) \
300: bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
301: #define CCU_WRITE(sc, reg, val) \
302: bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
303:
304: #endif /* _ARM_SUNXI_CCU_H */
CVSweb <webmaster@jp.NetBSD.org>