xref: /netbsd-src/sys/arch/arm/amlogic/meson_clk.h (revision 8afae5d5338994bf67aae444ff6e8ca504382a5e)
1*8afae5d5Sryo /* $NetBSD: meson_clk.h,v 1.4 2021/01/01 07:21:58 ryo Exp $ */
2912cfa14Sjmcneill 
3912cfa14Sjmcneill /*-
4912cfa14Sjmcneill  * Copyright (c) 2017-2019 Jared McNeill <jmcneill@invisible.ca>
5912cfa14Sjmcneill  * All rights reserved.
6912cfa14Sjmcneill  *
7912cfa14Sjmcneill  * Redistribution and use in source and binary forms, with or without
8912cfa14Sjmcneill  * modification, are permitted provided that the following conditions
9912cfa14Sjmcneill  * are met:
10912cfa14Sjmcneill  * 1. Redistributions of source code must retain the above copyright
11912cfa14Sjmcneill  *    notice, this list of conditions and the following disclaimer.
12912cfa14Sjmcneill  * 2. Redistributions in binary form must reproduce the above copyright
13912cfa14Sjmcneill  *    notice, this list of conditions and the following disclaimer in the
14912cfa14Sjmcneill  *    documentation and/or other materials provided with the distribution.
15912cfa14Sjmcneill  *
16912cfa14Sjmcneill  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17912cfa14Sjmcneill  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18912cfa14Sjmcneill  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19912cfa14Sjmcneill  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20912cfa14Sjmcneill  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21912cfa14Sjmcneill  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22912cfa14Sjmcneill  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23912cfa14Sjmcneill  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24912cfa14Sjmcneill  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25912cfa14Sjmcneill  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26912cfa14Sjmcneill  * SUCH DAMAGE.
27912cfa14Sjmcneill  */
28912cfa14Sjmcneill 
29912cfa14Sjmcneill #ifndef _ARM_MESON_CLK_H
30912cfa14Sjmcneill #define _ARM_MESON_CLK_H
31912cfa14Sjmcneill 
32912cfa14Sjmcneill #include <dev/clk/clk_backend.h>
337e38c880Sjmcneill #include <dev/fdt/syscon.h>
34912cfa14Sjmcneill 
35912cfa14Sjmcneill struct meson_clk_softc;
36912cfa14Sjmcneill struct meson_clk_clk;
37912cfa14Sjmcneill struct meson_clk_reset;
38912cfa14Sjmcneill 
39912cfa14Sjmcneill /*
40912cfa14Sjmcneill  * Resets
41912cfa14Sjmcneill  */
42912cfa14Sjmcneill 
43912cfa14Sjmcneill struct meson_clk_reset {
44912cfa14Sjmcneill 	bus_size_t	reg;
45912cfa14Sjmcneill 	uint32_t	mask;
46912cfa14Sjmcneill };
47912cfa14Sjmcneill 
48912cfa14Sjmcneill #define	MESON_CLK_RESET(_id, _reg, _bit)	\
49912cfa14Sjmcneill 	[_id] = {				\
50912cfa14Sjmcneill 		.reg = (_reg),			\
51912cfa14Sjmcneill 		.mask = __BIT(_bit),		\
52912cfa14Sjmcneill 	}
53912cfa14Sjmcneill 
54912cfa14Sjmcneill /*
55912cfa14Sjmcneill  * Clocks
56912cfa14Sjmcneill  */
57912cfa14Sjmcneill 
58912cfa14Sjmcneill enum meson_clk_clktype {
59912cfa14Sjmcneill 	MESON_CLK_UNKNOWN,
60912cfa14Sjmcneill 	MESON_CLK_FIXED,
61912cfa14Sjmcneill 	MESON_CLK_GATE,
62912cfa14Sjmcneill 	MESON_CLK_PLL,
63912cfa14Sjmcneill 	MESON_CLK_MPLL,
64912cfa14Sjmcneill 	MESON_CLK_DIV,
65912cfa14Sjmcneill 	MESON_CLK_FIXED_FACTOR,
66912cfa14Sjmcneill 	MESON_CLK_MUX,
67912cfa14Sjmcneill };
68912cfa14Sjmcneill 
69912cfa14Sjmcneill /*
70912cfa14Sjmcneill  * Fixed clocks
71912cfa14Sjmcneill  */
72912cfa14Sjmcneill 
73912cfa14Sjmcneill struct meson_clk_fixed {
74912cfa14Sjmcneill 	u_int		rate;
75912cfa14Sjmcneill };
76912cfa14Sjmcneill 
77912cfa14Sjmcneill u_int	meson_clk_fixed_get_rate(struct meson_clk_softc *, struct meson_clk_clk *);
78912cfa14Sjmcneill 
79912cfa14Sjmcneill #define	MESON_CLK_FIXED(_id, _name, _rate)			\
80912cfa14Sjmcneill 	[_id] = {						\
81912cfa14Sjmcneill 		.type = MESON_CLK_FIXED,			\
82912cfa14Sjmcneill 		.base.name = (_name),				\
83912cfa14Sjmcneill 		.base.flags = 0,				\
84912cfa14Sjmcneill 		.u.fixed.rate = (_rate),			\
85912cfa14Sjmcneill 		.get_rate = meson_clk_fixed_get_rate,		\
86912cfa14Sjmcneill 	}
87912cfa14Sjmcneill 
88912cfa14Sjmcneill /*
89912cfa14Sjmcneill  * Gate clocks
90912cfa14Sjmcneill  */
91912cfa14Sjmcneill 
92912cfa14Sjmcneill struct meson_clk_gate {
93912cfa14Sjmcneill 	bus_size_t	reg;
94912cfa14Sjmcneill 	uint32_t	mask;
95912cfa14Sjmcneill 	const char	*parent;
96912cfa14Sjmcneill 	uint32_t	flags;
97912cfa14Sjmcneill #define	MESON_CLK_GATE_SET_TO_DISABLE		__BIT(0)
98912cfa14Sjmcneill };
99912cfa14Sjmcneill 
100912cfa14Sjmcneill int	meson_clk_gate_enable(struct meson_clk_softc *,
101912cfa14Sjmcneill 			      struct meson_clk_clk *, int);
102912cfa14Sjmcneill const char *meson_clk_gate_get_parent(struct meson_clk_softc *,
103912cfa14Sjmcneill 				      struct meson_clk_clk *);
104912cfa14Sjmcneill 
105912cfa14Sjmcneill #define	MESON_CLK_GATE_FLAGS(_id, _name, _pname, _reg, _bit, _flags)	\
106912cfa14Sjmcneill 	[_id] = {						\
107912cfa14Sjmcneill 		.type = MESON_CLK_GATE,				\
108912cfa14Sjmcneill 		.base.name = (_name),				\
109912cfa14Sjmcneill 		.base.flags = CLK_SET_RATE_PARENT,		\
110912cfa14Sjmcneill 		.u.gate.parent = (_pname),			\
111912cfa14Sjmcneill 		.u.gate.reg = (_reg),				\
112912cfa14Sjmcneill 		.u.gate.mask = __BIT(_bit),			\
113912cfa14Sjmcneill 		.u.gate.flags = (_flags),			\
114912cfa14Sjmcneill 		.enable = meson_clk_gate_enable,		\
115912cfa14Sjmcneill 		.get_parent = meson_clk_gate_get_parent,	\
116912cfa14Sjmcneill 	}
117912cfa14Sjmcneill 
118912cfa14Sjmcneill #define	MESON_CLK_GATE(_id, _name, _pname, _reg, _bit)		\
119912cfa14Sjmcneill 	MESON_CLK_GATE_FLAGS(_id, _name, _pname, _reg, _bit, 0)
120912cfa14Sjmcneill 
121912cfa14Sjmcneill /*
122912cfa14Sjmcneill  * Divider clocks
123912cfa14Sjmcneill  */
124912cfa14Sjmcneill 
125912cfa14Sjmcneill struct meson_clk_div {
126912cfa14Sjmcneill 	bus_size_t	reg;
127912cfa14Sjmcneill 	const char	*parent;
128912cfa14Sjmcneill 	uint32_t	div;
129912cfa14Sjmcneill 	uint32_t	flags;
130912cfa14Sjmcneill #define	MESON_CLK_DIV_POWER_OF_TWO	__BIT(0)
131912cfa14Sjmcneill #define	MESON_CLK_DIV_SET_RATE_PARENT	__BIT(1)
132912cfa14Sjmcneill #define	MESON_CLK_DIV_CPU_SCALE_TABLE	__BIT(2)
133912cfa14Sjmcneill };
134912cfa14Sjmcneill 
135912cfa14Sjmcneill u_int	meson_clk_div_get_rate(struct meson_clk_softc *,
136912cfa14Sjmcneill 			       struct meson_clk_clk *);
137912cfa14Sjmcneill int	meson_clk_div_set_rate(struct meson_clk_softc *,
138912cfa14Sjmcneill 			       struct meson_clk_clk *, u_int);
139912cfa14Sjmcneill const char *meson_clk_div_get_parent(struct meson_clk_softc *,
140912cfa14Sjmcneill 				     struct meson_clk_clk *);
141912cfa14Sjmcneill 
142912cfa14Sjmcneill #define	MESON_CLK_DIV(_id, _name, _parent, _reg, _div, _flags)	\
143912cfa14Sjmcneill 	[_id] = {						\
144912cfa14Sjmcneill 		.type = MESON_CLK_DIV,				\
145912cfa14Sjmcneill 		.base.name = (_name),				\
146912cfa14Sjmcneill 		.u.div.reg = (_reg),				\
147912cfa14Sjmcneill 		.u.div.parent = (_parent),			\
148912cfa14Sjmcneill 		.u.div.div = (_div),				\
149912cfa14Sjmcneill 		.u.div.flags = (_flags),			\
150912cfa14Sjmcneill 		.get_rate = meson_clk_div_get_rate,		\
151912cfa14Sjmcneill 		.set_rate = meson_clk_div_set_rate,		\
152912cfa14Sjmcneill 		.get_parent = meson_clk_div_get_parent,		\
153912cfa14Sjmcneill 	}
154912cfa14Sjmcneill 
155912cfa14Sjmcneill /*
156912cfa14Sjmcneill  * Fixed-factor clocks
157912cfa14Sjmcneill  */
158912cfa14Sjmcneill 
159912cfa14Sjmcneill struct meson_clk_fixed_factor {
160912cfa14Sjmcneill 	const char	*parent;
161912cfa14Sjmcneill 	u_int		div;
162912cfa14Sjmcneill 	u_int		mult;
163912cfa14Sjmcneill };
164912cfa14Sjmcneill 
165912cfa14Sjmcneill u_int	meson_clk_fixed_factor_get_rate(struct meson_clk_softc *,
166912cfa14Sjmcneill 					struct meson_clk_clk *);
167912cfa14Sjmcneill int	meson_clk_fixed_factor_set_rate(struct meson_clk_softc *,
168912cfa14Sjmcneill 					struct meson_clk_clk *, u_int);
169912cfa14Sjmcneill const char *meson_clk_fixed_factor_get_parent(struct meson_clk_softc *,
170912cfa14Sjmcneill 					      struct meson_clk_clk *);
171912cfa14Sjmcneill 
172912cfa14Sjmcneill #define	MESON_CLK_FIXED_FACTOR(_id, _name, _parent, _div, _mult)	\
173912cfa14Sjmcneill 	[_id] = {							\
174912cfa14Sjmcneill 		.type = MESON_CLK_FIXED_FACTOR,				\
175912cfa14Sjmcneill 		.base.name = (_name),					\
176912cfa14Sjmcneill 		.u.fixed_factor.parent = (_parent),			\
177912cfa14Sjmcneill 		.u.fixed_factor.div = (_div),				\
178912cfa14Sjmcneill 		.u.fixed_factor.mult = (_mult),				\
179912cfa14Sjmcneill 		.get_rate = meson_clk_fixed_factor_get_rate,		\
180912cfa14Sjmcneill 		.get_parent = meson_clk_fixed_factor_get_parent,	\
181912cfa14Sjmcneill 		.set_rate = meson_clk_fixed_factor_set_rate,		\
182912cfa14Sjmcneill 	}
183912cfa14Sjmcneill 
184912cfa14Sjmcneill /*
185912cfa14Sjmcneill  * Mux clocks
186912cfa14Sjmcneill  */
187912cfa14Sjmcneill 
188912cfa14Sjmcneill struct meson_clk_mux {
189912cfa14Sjmcneill 	bus_size_t	reg;
190912cfa14Sjmcneill 	const char	**parents;
191912cfa14Sjmcneill 	u_int		nparents;
192912cfa14Sjmcneill 	uint32_t	sel;
193912cfa14Sjmcneill 	uint32_t	flags;
194912cfa14Sjmcneill };
195912cfa14Sjmcneill 
196912cfa14Sjmcneill const char *meson_clk_mux_get_parent(struct meson_clk_softc *,
197912cfa14Sjmcneill 			       struct meson_clk_clk *);
198912cfa14Sjmcneill 
199*8afae5d5Sryo #define	MESON_CLK_MUX_RATE(_id, _name, _parents, _reg, _sel,		\
200*8afae5d5Sryo 			   _getratefn, _setratefn, _flags)		\
201*8afae5d5Sryo 	[_id] = {							\
202*8afae5d5Sryo 		.type = MESON_CLK_MUX,					\
203*8afae5d5Sryo 		.base.name = (_name),					\
204*8afae5d5Sryo 		.base.flags = 0,					\
205*8afae5d5Sryo 		.u.mux.parents = (_parents),				\
206*8afae5d5Sryo 		.u.mux.nparents = __arraycount(_parents),		\
207*8afae5d5Sryo 		.u.mux.reg = (_reg),					\
208*8afae5d5Sryo 		.u.mux.sel = (_sel),					\
209*8afae5d5Sryo 		.u.mux.flags = (_flags),				\
210*8afae5d5Sryo 		.get_rate = _getratefn,					\
211*8afae5d5Sryo 		.set_rate = _setratefn,					\
212*8afae5d5Sryo 		.get_parent = meson_clk_mux_get_parent,			\
213*8afae5d5Sryo 	}
214*8afae5d5Sryo 
215912cfa14Sjmcneill #define	MESON_CLK_MUX(_id, _name, _parents, _reg, _sel, _flags)		\
216912cfa14Sjmcneill 	[_id] = {							\
217912cfa14Sjmcneill 		.type = MESON_CLK_MUX,					\
218912cfa14Sjmcneill 		.base.name = (_name),					\
219bce8d6d7Sjmcneill 		.base.flags = CLK_SET_RATE_PARENT,			\
220912cfa14Sjmcneill 		.u.mux.parents = (_parents),				\
221912cfa14Sjmcneill 		.u.mux.nparents = __arraycount(_parents),		\
222912cfa14Sjmcneill 		.u.mux.reg = (_reg),					\
223912cfa14Sjmcneill 		.u.mux.sel = (_sel),					\
224912cfa14Sjmcneill 		.u.mux.flags = (_flags),				\
225912cfa14Sjmcneill 		.get_parent = meson_clk_mux_get_parent,			\
226912cfa14Sjmcneill 	}
227912cfa14Sjmcneill 
228912cfa14Sjmcneill /*
229912cfa14Sjmcneill  * PLL clocks
230912cfa14Sjmcneill  */
231912cfa14Sjmcneill 
232912cfa14Sjmcneill struct meson_clk_pll_reg {
233912cfa14Sjmcneill 	bus_size_t	reg;
234912cfa14Sjmcneill 	uint32_t	mask;
235912cfa14Sjmcneill };
236912cfa14Sjmcneill 
237912cfa14Sjmcneill #define	MESON_CLK_PLL_REG(_reg, _mask)					\
238912cfa14Sjmcneill 	{ .reg = (_reg), .mask = (_mask) }
239912cfa14Sjmcneill #define	MESON_CLK_PLL_REG_INVALID	MESON_CLK_PLL_REG(0,0)
240912cfa14Sjmcneill 
241912cfa14Sjmcneill struct meson_clk_pll {
242912cfa14Sjmcneill 	struct meson_clk_pll_reg	enable;
243912cfa14Sjmcneill 	struct meson_clk_pll_reg	m;
244912cfa14Sjmcneill 	struct meson_clk_pll_reg	n;
245912cfa14Sjmcneill 	struct meson_clk_pll_reg	frac;
246912cfa14Sjmcneill 	struct meson_clk_pll_reg	l;
247912cfa14Sjmcneill 	struct meson_clk_pll_reg	reset;
248912cfa14Sjmcneill 	const char			*parent;
249912cfa14Sjmcneill 	uint32_t			flags;
250912cfa14Sjmcneill };
251912cfa14Sjmcneill 
252912cfa14Sjmcneill u_int	meson_clk_pll_get_rate(struct meson_clk_softc *,
253912cfa14Sjmcneill 			       struct meson_clk_clk *);
254*8afae5d5Sryo int	meson_clk_pll_set_rate(struct meson_clk_softc *,
255*8afae5d5Sryo 			       struct meson_clk_clk *, u_int new_rate);
256912cfa14Sjmcneill const char *meson_clk_pll_get_parent(struct meson_clk_softc *,
257912cfa14Sjmcneill 				     struct meson_clk_clk *);
258*8afae5d5Sryo int	meson_clk_pll_wait_lock(struct meson_clk_softc *sc,
259*8afae5d5Sryo 				struct meson_clk_pll *pll);
260*8afae5d5Sryo 
261912cfa14Sjmcneill 
262bce8d6d7Sjmcneill #define	MESON_CLK_PLL_RATE(_id, _name, _parent, _enable, _m, _n, _frac, _l,	\
263bce8d6d7Sjmcneill 		      _reset, _setratefn, _flags)			\
264bce8d6d7Sjmcneill 	[_id] = {							\
265bce8d6d7Sjmcneill 		.type = MESON_CLK_PLL,					\
266bce8d6d7Sjmcneill 		.base.name = (_name),					\
267bce8d6d7Sjmcneill 		.u.pll.parent = (_parent),				\
268bce8d6d7Sjmcneill 		.u.pll.enable = _enable,				\
269bce8d6d7Sjmcneill 		.u.pll.m = _m,						\
270bce8d6d7Sjmcneill 		.u.pll.n = _n,						\
271bce8d6d7Sjmcneill 		.u.pll.frac = _frac,					\
272bce8d6d7Sjmcneill 		.u.pll.l = _l,						\
273bce8d6d7Sjmcneill 		.u.pll.reset = _reset,					\
274bce8d6d7Sjmcneill 		.u.pll.flags = (_flags),				\
275bce8d6d7Sjmcneill 		.set_rate = (_setratefn),				\
276bce8d6d7Sjmcneill 		.get_rate = meson_clk_pll_get_rate,			\
277bce8d6d7Sjmcneill 		.get_parent = meson_clk_pll_get_parent,			\
278bce8d6d7Sjmcneill 	}
279bce8d6d7Sjmcneill 
280912cfa14Sjmcneill #define	MESON_CLK_PLL(_id, _name, _parent, _enable, _m, _n, _frac, _l,	\
281912cfa14Sjmcneill 		      _reset, _flags)					\
282912cfa14Sjmcneill 	[_id] = {							\
283912cfa14Sjmcneill 		.type = MESON_CLK_PLL,					\
284912cfa14Sjmcneill 		.base.name = (_name),					\
285912cfa14Sjmcneill 		.u.pll.parent = (_parent),				\
286912cfa14Sjmcneill 		.u.pll.enable = _enable,				\
287912cfa14Sjmcneill 		.u.pll.m = _m,						\
288912cfa14Sjmcneill 		.u.pll.n = _n,						\
289912cfa14Sjmcneill 		.u.pll.frac = _frac,					\
290912cfa14Sjmcneill 		.u.pll.l = _l,						\
291912cfa14Sjmcneill 		.u.pll.reset = _reset,					\
292912cfa14Sjmcneill 		.u.pll.flags = (_flags),				\
293912cfa14Sjmcneill 		.get_rate = meson_clk_pll_get_rate,			\
294912cfa14Sjmcneill 		.get_parent = meson_clk_pll_get_parent,			\
295912cfa14Sjmcneill 	}
296912cfa14Sjmcneill 
297912cfa14Sjmcneill /*
298912cfa14Sjmcneill  * MPLL clocks
299912cfa14Sjmcneill  */
300912cfa14Sjmcneill 
301912cfa14Sjmcneill struct meson_clk_mpll {
302912cfa14Sjmcneill 	struct meson_clk_pll_reg	sdm;
303912cfa14Sjmcneill 	struct meson_clk_pll_reg	sdm_enable;
304912cfa14Sjmcneill 	struct meson_clk_pll_reg	n2;
305912cfa14Sjmcneill 	struct meson_clk_pll_reg	ssen;
306912cfa14Sjmcneill 	const char			*parent;
307912cfa14Sjmcneill 	uint32_t			flags;
308912cfa14Sjmcneill };
309912cfa14Sjmcneill 
310912cfa14Sjmcneill u_int	meson_clk_mpll_get_rate(struct meson_clk_softc *,
311912cfa14Sjmcneill 				struct meson_clk_clk *);
312912cfa14Sjmcneill const char *meson_clk_mpll_get_parent(struct meson_clk_softc *,
313912cfa14Sjmcneill 				      struct meson_clk_clk *);
314912cfa14Sjmcneill 
315912cfa14Sjmcneill #define	MESON_CLK_MPLL(_id, _name, _parent, _sdm, _sdm_enable, _n2,	\
316912cfa14Sjmcneill 		       _ssen, _flags)					\
317912cfa14Sjmcneill 	[_id] = {							\
318912cfa14Sjmcneill 		.type = MESON_CLK_MPLL,					\
319912cfa14Sjmcneill 		.base.name = (_name),					\
320912cfa14Sjmcneill 		.u.mpll.parent = (_parent),				\
321912cfa14Sjmcneill 		.u.mpll.sdm = _sdm,					\
322912cfa14Sjmcneill 		.u.mpll.sdm_enable = _sdm_enable,			\
323912cfa14Sjmcneill 		.u.mpll.n2 = _n2,					\
324912cfa14Sjmcneill 		.u.mpll.ssen = _ssen,					\
325912cfa14Sjmcneill 		.u.mpll.flags = (_flags),				\
326912cfa14Sjmcneill 		.get_rate = meson_clk_mpll_get_rate,			\
327912cfa14Sjmcneill 		.get_parent = meson_clk_mpll_get_parent,		\
328912cfa14Sjmcneill 	}
329912cfa14Sjmcneill 
330912cfa14Sjmcneill 
331912cfa14Sjmcneill 
332912cfa14Sjmcneill struct meson_clk_clk {
333912cfa14Sjmcneill 	struct clk	base;
334912cfa14Sjmcneill 	enum meson_clk_clktype type;
335912cfa14Sjmcneill 	union {
336912cfa14Sjmcneill 		struct meson_clk_fixed fixed;
337912cfa14Sjmcneill 		struct meson_clk_gate gate;
338912cfa14Sjmcneill 		struct meson_clk_div div;
339912cfa14Sjmcneill 		struct meson_clk_fixed_factor fixed_factor;
340912cfa14Sjmcneill 		struct meson_clk_mux mux;
341912cfa14Sjmcneill 		struct meson_clk_pll pll;
342912cfa14Sjmcneill 		struct meson_clk_mpll mpll;
343912cfa14Sjmcneill 	} u;
344912cfa14Sjmcneill 
345912cfa14Sjmcneill 	int		(*enable)(struct meson_clk_softc *,
346912cfa14Sjmcneill 				  struct meson_clk_clk *, int);
347912cfa14Sjmcneill 	u_int		(*get_rate)(struct meson_clk_softc *,
348912cfa14Sjmcneill 				    struct meson_clk_clk *);
349912cfa14Sjmcneill 	int		(*set_rate)(struct meson_clk_softc *,
350912cfa14Sjmcneill 				    struct meson_clk_clk *, u_int);
351912cfa14Sjmcneill 	u_int		(*round_rate)(struct meson_clk_softc *,
352912cfa14Sjmcneill 				    struct meson_clk_clk *, u_int);
353912cfa14Sjmcneill 	const char *	(*get_parent)(struct meson_clk_softc *,
354912cfa14Sjmcneill 				      struct meson_clk_clk *);
355912cfa14Sjmcneill 	int		(*set_parent)(struct meson_clk_softc *,
356912cfa14Sjmcneill 				      struct meson_clk_clk *,
357912cfa14Sjmcneill 				      const char *);
358912cfa14Sjmcneill };
359912cfa14Sjmcneill 
360912cfa14Sjmcneill struct meson_clk_softc {
361912cfa14Sjmcneill 	device_t		sc_dev;
362912cfa14Sjmcneill 	int			sc_phandle;
3637e38c880Sjmcneill 
364912cfa14Sjmcneill 	bus_space_tag_t		sc_bst;
365912cfa14Sjmcneill 	bus_space_handle_t	sc_bsh;
366912cfa14Sjmcneill 
3677e38c880Sjmcneill 	struct syscon		*sc_syscon;
3687e38c880Sjmcneill 
369912cfa14Sjmcneill 	struct clk_domain	sc_clkdom;
370912cfa14Sjmcneill 
371912cfa14Sjmcneill 	struct meson_clk_reset *sc_resets;
372912cfa14Sjmcneill 	u_int			sc_nresets;
373912cfa14Sjmcneill 
374912cfa14Sjmcneill 	struct meson_clk_clk	*sc_clks;
375912cfa14Sjmcneill 	u_int			sc_nclks;
376912cfa14Sjmcneill };
377912cfa14Sjmcneill 
3787e38c880Sjmcneill void	meson_clk_attach(struct meson_clk_softc *);
379912cfa14Sjmcneill struct meson_clk_clk *meson_clk_clock_find(struct meson_clk_softc *,
380912cfa14Sjmcneill 					   const char *);
381912cfa14Sjmcneill void	meson_clk_print(struct meson_clk_softc *);
382912cfa14Sjmcneill 
3837e38c880Sjmcneill void	meson_clk_lock(struct meson_clk_softc *);
3847e38c880Sjmcneill void	meson_clk_unlock(struct meson_clk_softc *);
3857e38c880Sjmcneill uint32_t meson_clk_read(struct meson_clk_softc *, bus_size_t);
3867e38c880Sjmcneill void	meson_clk_write(struct meson_clk_softc *, bus_size_t, uint32_t);
3877e38c880Sjmcneill 
3887e38c880Sjmcneill #define	CLK_LOCK	meson_clk_lock
3897e38c880Sjmcneill #define	CLK_UNLOCK	meson_clk_unlock
3907e38c880Sjmcneill #define	CLK_READ	meson_clk_read
3917e38c880Sjmcneill #define	CLK_WRITE	meson_clk_write
392*8afae5d5Sryo #define CLK_WRITE_BITS(sc, reg, mask, val)			\
393*8afae5d5Sryo 	do {							\
394*8afae5d5Sryo 		uint32_t _cwb_tmp_ = CLK_READ((sc), (reg));	\
395*8afae5d5Sryo 		_cwb_tmp_ &= ~(mask);				\
396*8afae5d5Sryo 		_cwb_tmp_ |= __SHIFTIN((val), (mask));		\
397*8afae5d5Sryo 		CLK_WRITE((sc), (reg), _cwb_tmp_);		\
398*8afae5d5Sryo 	} while (0 /*CONSTCOND*/)
399912cfa14Sjmcneill 
400912cfa14Sjmcneill #endif /* _ARM_MESON_CLK_H */
401