xref: /netbsd-src/sys/arch/arm/sunxi/sunxi_ccu.h (revision f001abf4c1c042ccf378c1e0b9c9ebec18a12c73)
1 /* $NetBSD: sunxi_ccu.h,v 1.24 2024/09/16 23:37:13 macallan Exp $ */
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,
61 	SUNXI_CCU_NKMP,
62 	SUNXI_CCU_PREDIV,
63 	SUNXI_CCU_DIV,
64 	SUNXI_CCU_PHASE,
65 	SUNXI_CCU_FIXED_FACTOR,
66 	SUNXI_CCU_FRACTIONAL,
67 	SUNXI_CCU_MUX,
68 };
69 
70 struct sunxi_ccu_gate {
71 	bus_size_t	reg;
72 	uint32_t	mask;
73 	const char	*parent;
74 };
75 
76 int	sunxi_ccu_gate_enable(struct sunxi_ccu_softc *,
77 			      struct sunxi_ccu_clk *, int);
78 const char *sunxi_ccu_gate_get_parent(struct sunxi_ccu_softc *,
79 				      struct sunxi_ccu_clk *);
80 
81 #define	SUNXI_CCU_GATE(_id, _name, _pname, _reg, _bit)		\
82 	[_id] = {						\
83 		.type = SUNXI_CCU_GATE,				\
84 		.base.name = (_name),				\
85 		.base.flags = CLK_SET_RATE_PARENT,		\
86 		.u.gate.parent = (_pname),			\
87 		.u.gate.reg = (_reg),				\
88 		.u.gate.mask = __BIT(_bit),			\
89 		.enable = sunxi_ccu_gate_enable,		\
90 		.get_parent = sunxi_ccu_gate_get_parent,	\
91 	}
92 
93 struct sunxi_ccu_nkmp_tbl {
94 	u_int		rate;
95 	uint32_t	n;
96 	uint32_t	k;
97 	uint32_t	m;
98 	uint32_t	p;
99 };
100 
101 struct sunxi_ccu_nkmp {
102 	bus_size_t	reg;
103 	const char	*parent;
104 	uint32_t	n;
105 	uint32_t	k;
106 	uint32_t	m;
107 	uint32_t	p;
108 	uint32_t	lock;
109 	uint32_t	enable;
110 	uint32_t	flags;
111 	const struct sunxi_ccu_nkmp_tbl *table;
112 #define	SUNXI_CCU_NKMP_DIVIDE_BY_TWO		__BIT(0)
113 #define	SUNXI_CCU_NKMP_FACTOR_N_EXACT		__BIT(1)
114 #define	SUNXI_CCU_NKMP_SCALE_CLOCK		__BIT(2)
115 #define	SUNXI_CCU_NKMP_FACTOR_P_POW2		__BIT(3)
116 #define	SUNXI_CCU_NKMP_FACTOR_N_ZERO_IS_ONE	__BIT(4)
117 #define	SUNXI_CCU_NKMP_FACTOR_P_X4		__BIT(5)
118 };
119 
120 int	sunxi_ccu_nkmp_enable(struct sunxi_ccu_softc *,
121 			      struct sunxi_ccu_clk *, int);
122 u_int	sunxi_ccu_nkmp_get_rate(struct sunxi_ccu_softc *,
123 				struct sunxi_ccu_clk *);
124 int	sunxi_ccu_nkmp_set_rate(struct sunxi_ccu_softc *,
125 				struct sunxi_ccu_clk *, u_int);
126 const char *sunxi_ccu_nkmp_get_parent(struct sunxi_ccu_softc *,
127 				      struct sunxi_ccu_clk *);
128 
129 #define	SUNXI_CCU_NKMP_TABLE(_id, _name, _parent, _reg, _n, _k, _m, \
130 		       _p, _enable, _lock, _tbl, _flags)	\
131 	[_id] = {						\
132 		.type = SUNXI_CCU_NKMP,				\
133 		.base.name = (_name),				\
134 		.u.nkmp.reg = (_reg),				\
135 		.u.nkmp.parent = (_parent),			\
136 		.u.nkmp.n = (_n),				\
137 		.u.nkmp.k = (_k),				\
138 		.u.nkmp.m = (_m),				\
139 		.u.nkmp.p = (_p),				\
140 		.u.nkmp.enable = (_enable),			\
141 		.u.nkmp.flags = (_flags),			\
142 		.u.nkmp.lock = (_lock),				\
143 		.u.nkmp.table = (_tbl),				\
144 		.enable = sunxi_ccu_nkmp_enable,		\
145 		.get_rate = sunxi_ccu_nkmp_get_rate,		\
146 		.set_rate = sunxi_ccu_nkmp_set_rate,		\
147 		.get_parent = sunxi_ccu_nkmp_get_parent,	\
148 	}
149 
150 #define	SUNXI_CCU_NKMP(_id, _name, _parent, _reg, _n, _k, _m,	\
151 		       _p, _enable, _flags)			\
152 	SUNXI_CCU_NKMP_TABLE(_id, _name, _parent, _reg, _n, _k, _m, \
153 			     _p, _enable, 0, NULL, _flags)
154 
155 
156 struct sunxi_ccu_nm {
157 	bus_size_t	reg;
158 	const char	**parents;
159 	u_int		nparents;
160 	uint32_t	n;
161 	uint32_t	m;
162 	uint32_t	sel;
163 	uint32_t	enable;
164 	uint32_t	flags;
165 #define	SUNXI_CCU_NM_POWER_OF_TWO	__BIT(0)
166 #define	SUNXI_CCU_NM_ROUND_DOWN		__BIT(1)
167 #define	SUNXI_CCU_NM_DIVIDE_BY_TWO	__BIT(2)
168 };
169 
170 int	sunxi_ccu_nm_enable(struct sunxi_ccu_softc *,
171 			    struct sunxi_ccu_clk *, int);
172 u_int	sunxi_ccu_nm_get_rate(struct sunxi_ccu_softc *,
173 			      struct sunxi_ccu_clk *);
174 int	sunxi_ccu_nm_set_rate(struct sunxi_ccu_softc *,
175 			      struct sunxi_ccu_clk *, u_int);
176 int	sunxi_ccu_nm_set_parent(struct sunxi_ccu_softc *,
177 				struct sunxi_ccu_clk *,
178 				const char *);
179 const char *sunxi_ccu_nm_get_parent(struct sunxi_ccu_softc *,
180 				    struct sunxi_ccu_clk *);
181 
182 #define	SUNXI_CCU_NM(_id, _name, _parents, _reg, _n, _m, _sel,	\
183 		     _enable, _flags)				\
184 	[_id] = {						\
185 		.type = SUNXI_CCU_NM,				\
186 		.base.name = (_name),				\
187 		.u.nm.reg = (_reg),				\
188 		.u.nm.parents = (_parents),			\
189 		.u.nm.nparents = __arraycount(_parents),	\
190 		.u.nm.n = (_n),					\
191 		.u.nm.m = (_m),					\
192 		.u.nm.sel = (_sel),				\
193 		.u.nm.enable = (_enable),			\
194 		.u.nm.flags = (_flags),				\
195 		.enable = sunxi_ccu_nm_enable,			\
196 		.get_rate = sunxi_ccu_nm_get_rate,		\
197 		.set_rate = sunxi_ccu_nm_set_rate,		\
198 		.set_parent = sunxi_ccu_nm_set_parent,		\
199 		.get_parent = sunxi_ccu_nm_get_parent,		\
200 	}
201 
202 struct sunxi_ccu_div {
203 	bus_size_t	reg;
204 	const char	**parents;
205 	u_int		nparents;
206 	uint32_t	div;
207 	uint32_t	sel;
208 	uint32_t	enable;
209 	uint32_t	flags;
210 #define	SUNXI_CCU_DIV_POWER_OF_TWO	__BIT(0)
211 #define	SUNXI_CCU_DIV_ZERO_IS_ONE	__BIT(1)
212 #define	SUNXI_CCU_DIV_TIMES_TWO		__BIT(2)
213 #define	SUNXI_CCU_DIV_SET_RATE_PARENT	__BIT(3)
214 };
215 
216 int	sunxi_ccu_div_enable(struct sunxi_ccu_softc *,
217 			     struct sunxi_ccu_clk *, int);
218 u_int	sunxi_ccu_div_get_rate(struct sunxi_ccu_softc *,
219 			       struct sunxi_ccu_clk *);
220 int	sunxi_ccu_div_set_rate(struct sunxi_ccu_softc *,
221 			       struct sunxi_ccu_clk *, u_int);
222 int	sunxi_ccu_div_set_parent(struct sunxi_ccu_softc *,
223 			         struct sunxi_ccu_clk *,
224 			         const char *);
225 const char *sunxi_ccu_div_get_parent(struct sunxi_ccu_softc *,
226 				     struct sunxi_ccu_clk *);
227 
228 #define	SUNXI_CCU_DIV(_id, _name, _parents, _reg, _div,		\
229 		      _sel, _flags)				\
230 	SUNXI_CCU_DIV_GATE(_id, _name, _parents, _reg, _div,	\
231 			   _sel, 0, _flags)
232 
233 #define	SUNXI_CCU_DIV_GATE(_id, _name, _parents, _reg, _div,	\
234 		      _sel, _enable, _flags)			\
235 	[_id] = {						\
236 		.type = SUNXI_CCU_DIV,				\
237 		.base.name = (_name),				\
238 		.u.div.reg = (_reg),				\
239 		.u.div.parents = (_parents),			\
240 		.u.div.nparents = __arraycount(_parents),	\
241 		.u.div.div = (_div),				\
242 		.u.div.sel = (_sel),				\
243 		.u.div.enable = (_enable),			\
244 		.u.div.flags = (_flags),			\
245 		.enable = sunxi_ccu_div_enable,			\
246 		.get_rate = sunxi_ccu_div_get_rate,		\
247 		.set_rate = sunxi_ccu_div_set_rate,		\
248 		.set_parent = sunxi_ccu_div_set_parent,		\
249 		.get_parent = sunxi_ccu_div_get_parent,		\
250 	}
251 
252 /* special case of the div model for display clocks */
253 int sunxi_ccu_lcdxch0_set_rate(struct sunxi_ccu_softc *,
254     struct sunxi_ccu_clk *, struct sunxi_ccu_clk *,
255     struct sunxi_ccu_clk *, u_int);
256 u_int sunxi_ccu_lcdxch0_round_rate(struct sunxi_ccu_softc *,
257     struct sunxi_ccu_clk *, struct sunxi_ccu_clk *,
258     struct sunxi_ccu_clk *, u_int);
259 
260 int sunxi_ccu_lcdxch1_set_rate(struct sunxi_ccu_softc *sc,
261     struct sunxi_ccu_clk *clk, struct sunxi_ccu_clk *pclk,
262     struct sunxi_ccu_clk *pclk_x2, u_int);
263 
264 struct sunxi_ccu_prediv {
265 	bus_size_t	reg;
266 	const char	**parents;
267 	u_int		nparents;
268 	uint32_t	prediv;
269 	uint32_t	prediv_sel;
270 	uint32_t	prediv_fixed;
271 	uint32_t	div;
272 	uint32_t	sel;
273 	uint32_t	flags;
274 #define	SUNXI_CCU_PREDIV_POWER_OF_TWO	__BIT(0)
275 #define	SUNXI_CCU_PREDIV_DIVIDE_BY_TWO	__BIT(1)
276 };
277 
278 u_int	sunxi_ccu_prediv_get_rate(struct sunxi_ccu_softc *,
279 				  struct sunxi_ccu_clk *);
280 int	sunxi_ccu_prediv_set_rate(struct sunxi_ccu_softc *,
281 				  struct sunxi_ccu_clk *, u_int);
282 int	sunxi_ccu_prediv_set_parent(struct sunxi_ccu_softc *,
283 				    struct sunxi_ccu_clk *,
284 				    const char *);
285 const char *sunxi_ccu_prediv_get_parent(struct sunxi_ccu_softc *,
286 					struct sunxi_ccu_clk *);
287 
288 #define	SUNXI_CCU_PREDIV(_id, _name, _parents, _reg, _prediv,	\
289 		     _prediv_sel, _div, _sel, _flags)		\
290 	SUNXI_CCU_PREDIV_FIXED(_id, _name, _parents, _reg, _prediv, \
291 		     _prediv_sel, 0, _div, _sel, _flags)
292 
293 #define	SUNXI_CCU_PREDIV_FIXED(_id, _name, _parents, _reg, _prediv, \
294 		     _prediv_sel, _prediv_fixed, _div, _sel, _flags) \
295 	[_id] = {						\
296 		.type = SUNXI_CCU_PREDIV,			\
297 		.base.name = (_name),				\
298 		.u.prediv.reg = (_reg),				\
299 		.u.prediv.parents = (_parents),			\
300 		.u.prediv.nparents = __arraycount(_parents),	\
301 		.u.prediv.prediv = (_prediv),			\
302 		.u.prediv.prediv_sel = (_prediv_sel),		\
303 		.u.prediv.prediv_fixed = (_prediv_fixed),	\
304 		.u.prediv.div = (_div),				\
305 		.u.prediv.sel = (_sel),				\
306 		.u.prediv.flags = (_flags),			\
307 		.get_rate = sunxi_ccu_prediv_get_rate,		\
308 		.set_rate = sunxi_ccu_prediv_set_rate,		\
309 		.set_parent = sunxi_ccu_prediv_set_parent,	\
310 		.get_parent = sunxi_ccu_prediv_get_parent,	\
311 	}
312 
313 struct sunxi_ccu_phase {
314 	bus_size_t	reg;
315 	const char	*parent;
316 	uint32_t	mask;
317 };
318 
319 u_int	sunxi_ccu_phase_get_rate(struct sunxi_ccu_softc *,
320 				 struct sunxi_ccu_clk *);
321 int	sunxi_ccu_phase_set_rate(struct sunxi_ccu_softc *,
322 				 struct sunxi_ccu_clk *, u_int);
323 const char *sunxi_ccu_phase_get_parent(struct sunxi_ccu_softc *,
324 				       struct sunxi_ccu_clk *);
325 
326 #define	SUNXI_CCU_PHASE(_id, _name, _parent, _reg, _mask)	\
327 	[_id] = {						\
328 		.type = SUNXI_CCU_PHASE,			\
329 		.base.name = (_name),				\
330 		.u.phase.reg = (_reg),				\
331 		.u.phase.parent = (_parent),			\
332 		.u.phase.mask = (_mask),			\
333 		.get_rate = sunxi_ccu_phase_get_rate,		\
334 		.set_rate = sunxi_ccu_phase_set_rate,		\
335 		.get_parent = sunxi_ccu_phase_get_parent,	\
336 	}
337 
338 struct sunxi_ccu_fixed_factor {
339 	const char	*parent;
340 	u_int		div;
341 	u_int		mult;
342 };
343 
344 u_int	sunxi_ccu_fixed_factor_get_rate(struct sunxi_ccu_softc *,
345 					struct sunxi_ccu_clk *);
346 int	sunxi_ccu_fixed_factor_set_rate(struct sunxi_ccu_softc *,
347 					struct sunxi_ccu_clk *, u_int);
348 const char *sunxi_ccu_fixed_factor_get_parent(struct sunxi_ccu_softc *,
349 					      struct sunxi_ccu_clk *);
350 
351 #define	SUNXI_CCU_FIXED_FACTOR(_id, _name, _parent, _div, _mult)	\
352 	[_id] = {							\
353 		.type = SUNXI_CCU_FIXED_FACTOR,				\
354 		.base.name = (_name),					\
355 		.u.fixed_factor.parent = (_parent),			\
356 		.u.fixed_factor.div = (_div),				\
357 		.u.fixed_factor.mult = (_mult),				\
358 		.get_rate = sunxi_ccu_fixed_factor_get_rate,		\
359 		.get_parent = sunxi_ccu_fixed_factor_get_parent,	\
360 		.set_rate = sunxi_ccu_fixed_factor_set_rate,		\
361 	}
362 
363 struct sunxi_ccu_fractional {
364 	bus_size_t	reg;
365 	const char	*parent;
366 	uint32_t	m;
367 	uint32_t	m_min;
368 	uint32_t	m_max;
369 	uint32_t	div_en;
370 	uint32_t	frac_sel;
371 	uint32_t	frac[2];
372 	uint32_t	prediv;
373 	uint32_t	prediv_val;
374 	uint32_t	enable;
375 	uint32_t	flags;
376 #define	SUNXI_CCU_FRACTIONAL_PLUSONE	__BIT(0)
377 #define	SUNXI_CCU_FRACTIONAL_SET_ENABLE	__BIT(1)
378 };
379 
380 int	sunxi_ccu_fractional_enable(struct sunxi_ccu_softc *,
381 			    struct sunxi_ccu_clk *, int);
382 u_int	sunxi_ccu_fractional_get_rate(struct sunxi_ccu_softc *,
383 			      struct sunxi_ccu_clk *);
384 int	sunxi_ccu_fractional_set_rate(struct sunxi_ccu_softc *,
385 			      struct sunxi_ccu_clk *, u_int);
386 u_int	sunxi_ccu_fractional_round_rate(struct sunxi_ccu_softc *,
387 			      struct sunxi_ccu_clk *, u_int);
388 const char *sunxi_ccu_fractional_get_parent(struct sunxi_ccu_softc *,
389 				    struct sunxi_ccu_clk *);
390 
391 #define	SUNXI_CCU_FRACTIONAL(_id, _name, _parent, _reg, _m, _m_min, _m_max, \
392 		     _div_en, _frac_sel, _frac0, _frac1, _prediv, _prediv_val, \
393 		     _enable, _flags)					\
394 	[_id] = {							\
395 		.type = SUNXI_CCU_FRACTIONAL,				\
396 		.base.name = (_name),					\
397 		.u.fractional.reg = (_reg),				\
398 		.u.fractional.parent = (_parent),			\
399 		.u.fractional.m = (_m),					\
400 		.u.fractional.m_min = (_m_min),				\
401 		.u.fractional.m_max = (_m_max),				\
402 		.u.fractional.prediv = (_prediv),			\
403 		.u.fractional.prediv_val = (_prediv_val),		\
404 		.u.fractional.div_en = (_div_en),			\
405 		.u.fractional.frac_sel = (_frac_sel),			\
406 		.u.fractional.frac[0] = (_frac0),			\
407 		.u.fractional.frac[1] = (_frac1),			\
408 		.u.fractional.enable = (_enable),			\
409 		.u.fractional.flags = (_flags),				\
410 		.enable = sunxi_ccu_fractional_enable,			\
411 		.get_rate = sunxi_ccu_fractional_get_rate,		\
412 		.set_rate = sunxi_ccu_fractional_set_rate,		\
413 		.round_rate = sunxi_ccu_fractional_round_rate,		\
414 		.get_parent = sunxi_ccu_fractional_get_parent,		\
415 	}
416 
417 struct sunxi_ccu_mux {
418 	bus_size_t	reg;
419 	const char	**parents;
420 	u_int		nparents;
421 	uint32_t	sel;
422 	uint32_t	flags;
423 };
424 
425 int	sunxi_ccu_mux_set_parent(struct sunxi_ccu_softc *,
426 				 struct sunxi_ccu_clk *,
427 				 const char *);
428 const char *sunxi_ccu_mux_get_parent(struct sunxi_ccu_softc *,
429 				     struct sunxi_ccu_clk *);
430 
431 #define	SUNXI_CCU_MUX(_id, _name, _parents, _reg, _sel, _flags)	\
432 	[_id] = {						\
433 		.type = SUNXI_CCU_MUX,				\
434 		.base.name = (_name),				\
435 		.base.flags = CLK_SET_RATE_PARENT,		\
436 		.u.mux.reg = (_reg),				\
437 		.u.mux.parents = (_parents),			\
438 		.u.mux.nparents = __arraycount(_parents),	\
439 		.u.mux.sel = (_sel),				\
440 		.u.mux.flags = (_flags),			\
441 		.set_parent = sunxi_ccu_mux_set_parent,		\
442 		.get_parent = sunxi_ccu_mux_get_parent,		\
443 	}
444 
445 
446 struct sunxi_ccu_clk {
447 	struct clk	base;
448 	enum sunxi_ccu_clktype type;
449 	union {
450 		struct sunxi_ccu_gate gate;
451 		struct sunxi_ccu_nm nm;
452 		struct sunxi_ccu_nkmp nkmp;
453 		struct sunxi_ccu_prediv prediv;
454 		struct sunxi_ccu_div div;
455 		struct sunxi_ccu_phase phase;
456 		struct sunxi_ccu_fixed_factor fixed_factor;
457 		struct sunxi_ccu_fractional fractional;
458 		struct sunxi_ccu_mux mux;
459 	} u;
460 
461 	int		(*enable)(struct sunxi_ccu_softc *,
462 				  struct sunxi_ccu_clk *, int);
463 	u_int		(*get_rate)(struct sunxi_ccu_softc *,
464 				    struct sunxi_ccu_clk *);
465 	int		(*set_rate)(struct sunxi_ccu_softc *,
466 				    struct sunxi_ccu_clk *, u_int);
467 	u_int		(*round_rate)(struct sunxi_ccu_softc *,
468 				    struct sunxi_ccu_clk *, u_int);
469 	const char *	(*get_parent)(struct sunxi_ccu_softc *,
470 				      struct sunxi_ccu_clk *);
471 	int		(*set_parent)(struct sunxi_ccu_softc *,
472 				      struct sunxi_ccu_clk *,
473 				      const char *);
474 };
475 
476 struct sunxi_ccu_softc {
477 	device_t		sc_dev;
478 	int			sc_phandle;
479 	bus_space_tag_t		sc_bst;
480 	bus_space_handle_t	sc_bsh;
481 
482 	struct clk_domain	sc_clkdom;
483 
484 	struct sunxi_ccu_reset *sc_resets;
485 	u_int			sc_nresets;
486 
487 	struct sunxi_ccu_clk	*sc_clks;
488 	u_int			sc_nclks;
489 };
490 
491 int	sunxi_ccu_attach(struct sunxi_ccu_softc *);
492 struct sunxi_ccu_clk *sunxi_ccu_clock_find(struct sunxi_ccu_softc *,
493 					   const char *);
494 void	sunxi_ccu_print(struct sunxi_ccu_softc *);
495 
496 #define CCU_READ(sc, reg)	\
497 	bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
498 #define CCU_WRITE(sc, reg, val)	\
499 	bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
500 
501 #endif /* _ARM_SUNXI_CCU_H */
502