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