sunxi_ccu.h revision 1.1
1/* $NetBSD: sunxi_ccu.h,v 1.1 2017/06/28 23:51:29 jmcneill 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
34struct sunxi_ccu_softc;
35struct sunxi_ccu_clk;
36struct sunxi_ccu_reset;
37
38/*
39 * Resets
40 */
41
42struct 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
57enum sunxi_ccu_clktype {
58	SUNXI_CCU_UNKNOWN,
59	SUNXI_CCU_GATE,
60	SUNXI_CCU_NM,
61};
62
63struct sunxi_ccu_gate {
64	bus_size_t	reg;
65	uint32_t	mask;
66	const char	*parent;
67};
68
69int	sunxi_ccu_gate_enable(struct sunxi_ccu_softc *,
70			      struct sunxi_ccu_clk *, int);
71const char *sunxi_ccu_gate_get_parent(struct sunxi_ccu_softc *,
72				      struct sunxi_ccu_clk *);
73
74#define	SUNXI_CCU_GATE(_id, _name, _pname, _reg, _bit)		\
75	[_id] = {						\
76		.type = SUNXI_CCU_GATE,				\
77		.base.name = (_name),				\
78		.u.gate.parent = (_pname),			\
79		.u.gate.reg = (_reg),				\
80		.u.gate.mask = __BIT(_bit),			\
81		.enable = sunxi_ccu_gate_enable,		\
82		.get_parent = sunxi_ccu_gate_get_parent,	\
83	}
84
85struct sunxi_ccu_nm {
86	bus_size_t	reg;
87	const char	**parents;
88	u_int		nparents;
89	uint32_t	n;
90	uint32_t	m;
91	uint32_t	sel;
92	uint32_t	flags;
93#define	SUNXI_CCU_NM_POWER_OF_TWO	__BIT(0)
94};
95
96u_int	sunxi_ccu_nm_get_rate(struct sunxi_ccu_softc *,
97			      struct sunxi_ccu_clk *);
98int	sunxi_ccu_nm_set_rate(struct sunxi_ccu_softc *,
99			      struct sunxi_ccu_clk *, u_int);
100int	sunxi_ccu_nm_set_parent(struct sunxi_ccu_softc *,
101				struct sunxi_ccu_clk *,
102				const char *);
103const char *sunxi_ccu_nm_get_parent(struct sunxi_ccu_softc *,
104				    struct sunxi_ccu_clk *);
105
106#define	SUNXI_CCU_NM(_id, _name, _parents, _reg, _n, _m, _sel,	\
107		     _flags)					\
108	[_id] = {						\
109		.type = SUNXI_CCU_NM,				\
110		.base.name = (_name),				\
111		.u.nm.reg = (_reg),				\
112		.u.nm.parents = (_parents),			\
113		.u.nm.nparents = __arraycount(_parents),	\
114		.u.nm.n = (_n),					\
115		.u.nm.m = (_m),					\
116		.u.nm.sel = (_sel),				\
117		.u.nm.flags = (_flags),				\
118		.set_parent = sunxi_ccu_nm_set_parent,		\
119		.get_parent = sunxi_ccu_nm_get_parent,		\
120	}
121
122struct sunxi_ccu_clk {
123	struct clk	base;
124	enum sunxi_ccu_clktype type;
125	union {
126		struct sunxi_ccu_gate gate;
127		struct sunxi_ccu_nm nm;
128	} u;
129
130	int		(*enable)(struct sunxi_ccu_softc *,
131				  struct sunxi_ccu_clk *, int);
132	u_int		(*get_rate)(struct sunxi_ccu_softc *,
133				    struct sunxi_ccu_clk *);
134	int		(*set_rate)(struct sunxi_ccu_softc *,
135				    struct sunxi_ccu_clk *, u_int);
136	const char *	(*get_parent)(struct sunxi_ccu_softc *,
137				      struct sunxi_ccu_clk *);
138	int		(*set_parent)(struct sunxi_ccu_softc *,
139				      struct sunxi_ccu_clk *,
140				      const char *);
141};
142
143struct sunxi_ccu_softc {
144	device_t		sc_dev;
145	int			sc_phandle;
146	bus_space_tag_t		sc_bst;
147	bus_space_handle_t	sc_bsh;
148
149	struct clk_domain	sc_clkdom;
150
151	struct sunxi_ccu_reset *sc_resets;
152	u_int			sc_nresets;
153
154	struct sunxi_ccu_clk	*sc_clks;
155	u_int			sc_nclks;
156};
157
158int	sunxi_ccu_attach(struct sunxi_ccu_softc *);
159struct sunxi_ccu_clk *sunxi_ccu_clock_find(struct sunxi_ccu_softc *,
160					   const char *);
161void	sunxi_ccu_print(struct sunxi_ccu_softc *);
162
163#define CCU_READ(sc, reg)	\
164	bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
165#define CCU_WRITE(sc, reg, val)	\
166	bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
167
168#endif /* _ARM_SUNXI_CCU_H */
169