xref: /openbsd/sys/dev/fdt/rkclock.c (revision 41b6ab1f)
1 /*	$OpenBSD: rkclock.c,v 1.91 2024/11/24 22:19:59 kettenis Exp $	*/
2 /*
3  * Copyright (c) 2017, 2018 Mark Kettenis <kettenis@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <sys/param.h>
19 #include <sys/systm.h>
20 #include <sys/sysctl.h>
21 #include <sys/device.h>
22 
23 #include <machine/intr.h>
24 #include <machine/bus.h>
25 #include <machine/fdt.h>
26 
27 #include <dev/ofw/openfirm.h>
28 #include <dev/ofw/ofw_clock.h>
29 #include <dev/ofw/ofw_misc.h>
30 #include <dev/ofw/fdt.h>
31 
32 /* RK3288 registers */
33 #define RK3288_CRU_APLL_CON(i)		(0x0000 + (i) * 4)
34 #define RK3288_CRU_CPLL_CON(i)		(0x0020 + (i) * 4)
35 #define RK3288_CRU_GPLL_CON(i)		(0x0030 + (i) * 4)
36 #define RK3288_CRU_NPLL_CON(i)		(0x0040 + (i) * 4)
37 #define  RK3288_CRU_PLL_CLKR_MASK		(0x3f << 8)
38 #define  RK3288_CRU_PLL_CLKR_SHIFT		8
39 #define  RK3288_CRU_PLL_CLKOD_MASK		(0xf << 0)
40 #define  RK3288_CRU_PLL_CLKOD_SHIFT		0
41 #define  RK3288_CRU_PLL_CLKF_MASK		(0x1fff << 0)
42 #define  RK3288_CRU_PLL_CLKF_SHIFT		0
43 #define  RK3288_CRU_PLL_RESET			(1 << 5)
44 #define RK3288_CRU_MODE_CON		0x0050
45 #define  RK3288_CRU_MODE_PLL_WORK_MODE_MASK	0x3
46 #define  RK3288_CRU_MODE_PLL_WORK_MODE_SLOW	0x0
47 #define  RK3288_CRU_MODE_PLL_WORK_MODE_NORMAL	0x1
48 #define RK3288_CRU_CLKSEL_CON(i)	(0x0060 + (i) * 4)
49 #define RK3288_CRU_SOFTRST_CON(i)	(0x01b8 + (i) * 4)
50 
51 /* RK3308 registers */
52 #define RK3308_CRU_APLL_CON(i)		(0x0000 + (i) * 4)
53 #define RK3308_CRU_DPLL_CON(i)		(0x0020 + (i) * 4)
54 #define RK3308_CRU_VPLL0_CON(i)		(0x0040 + (i) * 4)
55 #define RK3308_CRU_VPLL1_CON(i)		(0x0060 + (i) * 4)
56 #define  RK3308_CRU_PLL_POSTDIV1_MASK		(0x7 << 12)
57 #define  RK3308_CRU_PLL_POSTDIV1_SHIFT		12
58 #define  RK3308_CRU_PLL_FBDIV_MASK		(0xfff << 0)
59 #define  RK3308_CRU_PLL_FBDIV_SHIFT		0
60 #define  RK3308_CRU_PLL_DSMPD			(1 << 12)
61 #define  RK3308_CRU_PLL_PLL_LOCK		(1 << 10)
62 #define  RK3308_CRU_PLL_POSTDIV2_MASK		(0x7 << 6)
63 #define  RK3308_CRU_PLL_POSTDIV2_SHIFT		6
64 #define  RK3308_CRU_PLL_REFDIV_MASK		(0x3f << 0)
65 #define  RK3308_CRU_PLL_REFDIV_SHIFT		0
66 #define  RK3308_CRU_PLL_FRACDIV_MASK		(0xffffff << 0)
67 #define  RK3308_CRU_PLL_FRACDIV_SHIFT		0
68 #define RK3308_CRU_CRU_MODE		0x00a0
69 #define RK3308_CRU_CRU_MODE_MASK	0x3
70 #define RK3308_CRU_CRU_MODE_SLOW	0x0
71 #define RK3308_CRU_CRU_MODE_NORMAL	0x1
72 #define RK3308_CRU_CRU_MODE_DEEP	0x2
73 #define RK3308_CRU_CLKSEL_CON(i)	(0x0100 + (i) * 4)
74 #define  RK3308_CRU_ACLK_CORE_DIV_CON_MASK	(0x07 << 12)
75 #define  RK3308_CRU_ACLK_CORE_DIV_CON_SHIFT	12
76 #define  RK3308_CRU_CLK_CORE_DBG_DIV_CON_MASK	(0x0f << 8)
77 #define  RK3308_CRU_CLK_CORE_DBG_DIV_CON_SHIFT  8
78 #define  RK3308_CRU_CORE_CLK_PLL_SEL_MASK	(0x03 << 6)
79 #define  RK3308_CRU_CORE_CLK_PLL_SEL_SHIFT	6
80 #define  RK3308_CRU_CLK_CORE_DIV_CON_MASK	(0x0f << 0)
81 #define  RK3308_CRU_CLK_CORE_DIV_CON_SHIFT	0
82 #define RK3308_CRU_CLKGATE_CON(i)	(0x0300 + (i) * 4)
83 #define RK3308_CRU_SOFTRST_CON(i)	(0x0400 + (i) * 4)
84 
85 /* RK3328 registers */
86 #define RK3328_CRU_APLL_CON(i)		(0x0000 + (i) * 4)
87 #define RK3328_CRU_DPLL_CON(i)		(0x0020 + (i) * 4)
88 #define RK3328_CRU_CPLL_CON(i)		(0x0040 + (i) * 4)
89 #define RK3328_CRU_GPLL_CON(i)		(0x0060 + (i) * 4)
90 #define RK3328_CRU_NPLL_CON(i)		(0x00a0 + (i) * 4)
91 #define  RK3328_CRU_PLL_POSTDIV1_MASK		(0x7 << 12)
92 #define  RK3328_CRU_PLL_POSTDIV1_SHIFT		12
93 #define  RK3328_CRU_PLL_FBDIV_MASK		(0xfff << 0)
94 #define  RK3328_CRU_PLL_FBDIV_SHIFT		0
95 #define  RK3328_CRU_PLL_DSMPD			(1 << 12)
96 #define  RK3328_CRU_PLL_PLL_LOCK		(1 << 10)
97 #define  RK3328_CRU_PLL_POSTDIV2_MASK		(0x7 << 6)
98 #define  RK3328_CRU_PLL_POSTDIV2_SHIFT		6
99 #define  RK3328_CRU_PLL_REFDIV_MASK		(0x3f << 0)
100 #define  RK3328_CRU_PLL_REFDIV_SHIFT		0
101 #define  RK3328_CRU_PLL_FRACDIV_MASK		(0xffffff << 0)
102 #define  RK3328_CRU_PLL_FRACDIV_SHIFT		0
103 #define RK3328_CRU_CRU_MODE		0x0080
104 #define  RK3328_CRU_CRU_MODE_MASK		0x1
105 #define  RK3328_CRU_CRU_MODE_SLOW		0x0
106 #define  RK3328_CRU_CRU_MODE_NORMAL		0x1
107 #define RK3328_CRU_CLKSEL_CON(i)	(0x0100 + (i) * 4)
108 #define  RK3328_CRU_CORE_CLK_PLL_SEL_MASK	(0x3 << 6)
109 #define  RK3328_CRU_CORE_CLK_PLL_SEL_SHIFT	6
110 #define  RK3328_CRU_CLK_CORE_DIV_CON_MASK	(0x1f << 0)
111 #define  RK3328_CRU_CLK_CORE_DIV_CON_SHIFT	0
112 #define  RK3328_CRU_ACLK_CORE_DIV_CON_MASK	(0x7 << 4)
113 #define  RK3328_CRU_ACLK_CORE_DIV_CON_SHIFT	4
114 #define  RK3328_CRU_CLK_CORE_DBG_DIV_CON_MASK	(0xf << 0)
115 #define  RK3328_CRU_CLK_CORE_DBG_DIV_CON_SHIFT	0
116 #define  RK3328_CRU_VOP_DCLK_SRC_SEL_MASK	(0x1 << 1)
117 #define  RK3328_CRU_VOP_DCLK_SRC_SEL_SHIFT	1
118 #define RK3328_CRU_CLKGATE_CON(i)	(0x0200 + (i) * 4)
119 #define RK3328_CRU_SOFTRST_CON(i)	(0x0300 + (i) * 4)
120 
121 #define RK3328_GRF_SOC_CON4		0x0410
122 #define  RK3328_GRF_GMAC2IO_MAC_CLK_OUTPUT_EN	(1 << 14)
123 #define RK3328_GRF_MAC_CON1		0x0904
124 #define  RK3328_GRF_GMAC2IO_RMII_EXTCLK_SEL	(1 << 10)
125 
126 /* RK3399 registers */
127 #define RK3399_CRU_LPLL_CON(i)		(0x0000 + (i) * 4)
128 #define RK3399_CRU_BPLL_CON(i)		(0x0020 + (i) * 4)
129 #define RK3399_CRU_DPLL_CON(i)		(0x0020 + (i) * 4)
130 #define RK3399_CRU_CPLL_CON(i)		(0x0060 + (i) * 4)
131 #define RK3399_CRU_GPLL_CON(i)		(0x0080 + (i) * 4)
132 #define RK3399_CRU_NPLL_CON(i)		(0x00a0 + (i) * 4)
133 #define RK3399_CRU_VPLL_CON(i)		(0x00c0 + (i) * 4)
134 #define  RK3399_CRU_PLL_FBDIV_MASK		(0xfff << 0)
135 #define  RK3399_CRU_PLL_FBDIV_SHIFT		0
136 #define  RK3399_CRU_PLL_POSTDIV2_MASK		(0x7 << 12)
137 #define  RK3399_CRU_PLL_POSTDIV2_SHIFT		12
138 #define  RK3399_CRU_PLL_POSTDIV1_MASK		(0x7 << 8)
139 #define  RK3399_CRU_PLL_POSTDIV1_SHIFT		8
140 #define  RK3399_CRU_PLL_REFDIV_MASK		(0x3f << 0)
141 #define  RK3399_CRU_PLL_REFDIV_SHIFT		0
142 #define  RK3399_CRU_PLL_PLL_WORK_MODE_MASK	(0x3 << 8)
143 #define  RK3399_CRU_PLL_PLL_WORK_MODE_SLOW	(0x0 << 8)
144 #define  RK3399_CRU_PLL_PLL_WORK_MODE_NORMAL	(0x1 << 8)
145 #define  RK3399_CRU_PLL_PLL_WORK_MODE_DEEP_SLOW	(0x2 << 8)
146 #define  RK3399_CRU_PLL_PLL_LOCK		(1U << 31)
147 #define RK3399_CRU_CLKSEL_CON(i)	(0x0100 + (i) * 4)
148 #define  RK3399_CRU_ACLKM_CORE_DIV_CON_MASK	(0x1f << 8)
149 #define  RK3399_CRU_ACLKM_CORE_DIV_CON_SHIFT	8
150 #define  RK3399_CRU_CORE_PLL_SEL_MASK		(0x3 << 6)
151 #define  RK3399_CRU_CORE_PLL_SEL_APLL		(0x0 << 6)
152 #define  RK3399_CRU_CORE_PLL_SEL_BPLL		(0x1 << 6)
153 #define  RK3399_CRU_CORE_PLL_SEL_DPLL		(0x2 << 6)
154 #define  RK3399_CRU_CORE_PLL_SEL_GPLL		(0x3 << 6)
155 #define  RK3399_CRU_CORE_PLL_SEL_SHIFT		6
156 #define  RK3399_CRU_CLK_CORE_DIV_CON_MASK	(0x1f << 0)
157 #define  RK3399_CRU_CLK_CORE_DIV_CON_SHIFT	0
158 #define  RK3399_CRU_PCLK_DBG_DIV_CON_MASK	(0x1f << 8)
159 #define  RK3399_CRU_PCLK_DBG_DIV_CON_SHIFT	8
160 #define  RK3399_CRU_ATCLK_CORE_DIV_CON_MASK	(0x1f << 0)
161 #define  RK3399_CRU_ATCLK_CORE_DIV_CON_SHIFT	0
162 #define  RK3399_CRU_CLK_SD_PLL_SEL_MASK		(0x7 << 8)
163 #define  RK3399_CRU_CLK_SD_PLL_SEL_SHIFT	8
164 #define  RK3399_CRU_CLK_SD_DIV_CON_MASK		(0x7f << 0)
165 #define  RK3399_CRU_CLK_SD_DIV_CON_SHIFT	0
166 #define RK3399_CRU_CLKGATE_CON(i)	(0x0300 + (i) * 4)
167 #define RK3399_CRU_SOFTRST_CON(i)	(0x0400 + (i) * 4)
168 #define RK3399_CRU_SDMMC_CON(i)		(0x0580 + (i) * 4)
169 
170 #define RK3399_PMUCRU_PPLL_CON(i)	(0x0000 + (i) * 4)
171 #define RK3399_PMUCRU_CLKSEL_CON(i)	(0x0080 + (i) * 4)
172 
173 /* RK3568 registers */
174 #define RK3568_CRU_APLL_CON(i)		(0x0000 + (i) * 4)
175 #define RK3568_CRU_DPLL_CON(i)		(0x0020 + (i) * 4)
176 #define RK3568_CRU_GPLL_CON(i)		(0x0040 + (i) * 4)
177 #define RK3568_CRU_CPLL_CON(i)		(0x0060 + (i) * 4)
178 #define RK3568_CRU_NPLL_CON(i)		(0x0080 + (i) * 4)
179 #define RK3568_CRU_VPLL_CON(i)		(0x00a0 + (i) * 4)
180 #define RK3568_CRU_MODE_CON		0x00c0
181 #define RK3568_CRU_CLKSEL_CON(i)	(0x0100 + (i) * 4)
182 #define RK3568_CRU_GATE_CON(i)		(0x0300 + (i) * 4)
183 #define RK3568_CRU_SOFTRST_CON(i)	(0x0400 + (i) * 4)
184 
185 #define RK3568_PMUCRU_PPLL_CON(i)	(0x0000 + (i) * 4)
186 #define RK3568_PMUCRU_HPLL_CON(i)	(0x0040 + (i) * 4)
187 #define RK3568_PMUCRU_MODE_CON		0x0080
188 #define RK3568_PMUCRU_CLKSEL_CON(i)	(0x0100 + (i) * 4)
189 #define RK3568_PMUCRU_GATE_CON(i)	(0x0180 + (i) * 4)
190 
191 /* RK3588 registers */
192 #define RK3588_CRU_AUPLL_CON(i)		(0x00180 + (i) * 4)
193 #define RK3588_CRU_CPLL_CON(i)		(0x001a0 + (i) * 4)
194 #define RK3588_CRU_GPLL_CON(i)		(0x001c0 + (i) * 4)
195 #define RK3588_CRU_NPLL_CON(i)		(0x001e0 + (i) * 4)
196 #define  RK3588_CRU_PLL_M_MASK			(0x3ff << 0)
197 #define  RK3588_CRU_PLL_M_SHIFT			0
198 #define  RK3588_CRU_PLL_RESETB			(1 << 13)
199 #define  RK3588_CRU_PLL_S_MASK			(0x7 << 6)
200 #define  RK3588_CRU_PLL_S_SHIFT			6
201 #define  RK3588_CRU_PLL_P_MASK			(0x3f << 0)
202 #define  RK3588_CRU_PLL_P_SHIFT			0
203 #define  RK3588_CRU_PLL_K_MASK			(0xffff << 0)
204 #define  RK3588_CRU_PLL_K_SHIFT			0
205 #define  RK3588_CRU_PLL_PLL_LOCK		(1 << 15)
206 #define RK3588_CRU_MODE_CON		0x00280
207 #define  RK3588_CRU_MODE_MASK			0x3
208 #define  RK3588_CRU_MODE_SLOW			0x0
209 #define  RK3588_CRU_MODE_NORMAL			0x1
210 
211 #define RK3588_CRU_CLKSEL_CON(i)	(0x00300 + (i) * 4)
212 #define RK3588_CRU_GATE_CON(i)		(0x00800 + (i) * 4)
213 #define RK3588_CRU_SOFTRST_CON(i)	(0x00a00 + (i) * 4)
214 
215 #define RK3588_PHPTOPCRU_PPLL_CON(i)	(0x08200 + (i) * 4)
216 #define RK3588_PHPTOPCRU_SOFTRST_CON(i)	(0x08a00 + (i) * 4)
217 #define RK3588_PMUCRU_CLKSEL_CON(i)	(0x30300 + (i) * 4)
218 
219 #include "rkclock_clocks.h"
220 
221 struct rkclock {
222 	uint16_t idx;
223 	uint32_t reg;
224 	uint16_t sel_mask;
225 	uint16_t div_mask;
226 	uint16_t parents[8];
227 	uint32_t flags;
228 };
229 
230 #define SEL(l, f)	(((1 << (l - f + 1)) - 1) << f)
231 #define DIV(l, f)	SEL(l, f)
232 
233 #define FIXED_PARENT	(1 << 0)
234 #define SET_PARENT	(1 << 1)
235 
236 #define HREAD4(sc, reg)							\
237 	(bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg)))
238 #define HWRITE4(sc, reg, val)						\
239 	bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
240 #define HSET4(sc, reg, bits)						\
241 	HWRITE4((sc), (reg), HREAD4((sc), (reg)) | (bits))
242 #define HCLR4(sc, reg, bits)						\
243 	HWRITE4((sc), (reg), HREAD4((sc), (reg)) & ~(bits))
244 
245 struct rkclock_softc {
246 	struct device		sc_dev;
247 	bus_space_tag_t		sc_iot;
248 	bus_space_handle_t	sc_ioh;
249 	struct regmap		*sc_grf;
250 
251 	uint32_t		sc_phandle;
252 	const struct rkclock	*sc_clocks;
253 
254 	struct clock_device	sc_cd;
255 	struct reset_device	sc_rd;
256 };
257 
258 int rkclock_match(struct device *, void *, void *);
259 void rkclock_attach(struct device *, struct device *, void *);
260 
261 const struct cfattach	rkclock_ca = {
262 	sizeof (struct rkclock_softc), rkclock_match, rkclock_attach
263 };
264 
265 struct cfdriver rkclock_cd = {
266 	NULL, "rkclock", DV_DULL
267 };
268 
269 void	rk3288_init(struct rkclock_softc *);
270 uint32_t rk3288_get_frequency(void *, uint32_t *);
271 int	rk3288_set_frequency(void *, uint32_t *, uint32_t);
272 void	rk3288_enable(void *, uint32_t *, int);
273 void	rk3288_reset(void *, uint32_t *, int);
274 
275 void	rk3308_init(struct rkclock_softc *);
276 uint32_t rk3308_get_frequency(void *, uint32_t *);
277 int	rk3308_set_frequency(void *, uint32_t *, uint32_t);
278 int	rk3308_set_parent(void *, uint32_t *, uint32_t *);
279 void	rk3308_enable(void *, uint32_t *, int);
280 void	rk3308_reset(void *, uint32_t *, int);
281 
282 void	rk3328_init(struct rkclock_softc *);
283 uint32_t rk3328_get_frequency(void *, uint32_t *);
284 int	rk3328_set_frequency(void *, uint32_t *, uint32_t);
285 int	rk3328_set_parent(void *, uint32_t *, uint32_t *);
286 void	rk3328_enable(void *, uint32_t *, int);
287 void	rk3328_reset(void *, uint32_t *, int);
288 
289 void	rk3399_init(struct rkclock_softc *);
290 uint32_t rk3399_get_frequency(void *, uint32_t *);
291 int	rk3399_set_frequency(void *, uint32_t *, uint32_t);
292 int	rk3399_set_parent(void *, uint32_t *, uint32_t *);
293 void	rk3399_enable(void *, uint32_t *, int);
294 void	rk3399_reset(void *, uint32_t *, int);
295 
296 void	rk3399_pmu_init(struct rkclock_softc *);
297 uint32_t rk3399_pmu_get_frequency(void *, uint32_t *);
298 int	rk3399_pmu_set_frequency(void *, uint32_t *, uint32_t);
299 void	rk3399_pmu_enable(void *, uint32_t *, int);
300 void	rk3399_pmu_reset(void *, uint32_t *, int);
301 
302 void	rk3568_init(struct rkclock_softc *);
303 uint32_t rk3568_get_frequency(void *, uint32_t *);
304 int	rk3568_set_frequency(void *, uint32_t *, uint32_t);
305 int	rk3568_set_parent(void *, uint32_t *, uint32_t *);
306 void	rk3568_enable(void *, uint32_t *, int);
307 void	rk3568_reset(void *, uint32_t *, int);
308 
309 void	rk3568_pmu_init(struct rkclock_softc *);
310 uint32_t rk3568_pmu_get_frequency(void *, uint32_t *);
311 int	rk3568_pmu_set_frequency(void *, uint32_t *, uint32_t);
312 void	rk3568_pmu_enable(void *, uint32_t *, int);
313 void	rk3568_pmu_reset(void *, uint32_t *, int);
314 
315 void	rk3588_init(struct rkclock_softc *);
316 uint32_t rk3588_get_frequency(void *, uint32_t *);
317 int	rk3588_set_frequency(void *, uint32_t *, uint32_t);
318 void	rk3588_enable(void *, uint32_t *, int);
319 void	rk3588_reset(void *, uint32_t *, int);
320 
321 struct rkclock_compat {
322 	const char *compat;
323 	const char *name;
324 	int	assign;
325 	void	(*init)(struct rkclock_softc *);
326 	void	(*enable)(void *, uint32_t *, int);
327 	uint32_t (*get_frequency)(void *, uint32_t *);
328 	int	(*set_frequency)(void *, uint32_t *, uint32_t);
329 	int	(*set_parent)(void *, uint32_t *, uint32_t *);
330 	void	(*reset)(void *, uint32_t *, int);
331 };
332 
333 const struct rkclock_compat rkclock_compat[] = {
334 	{
335 		"rockchip,rk3288-cru", NULL, 0, rk3288_init,
336 		rk3288_enable, rk3288_get_frequency,
337 		rk3288_set_frequency, NULL,
338 		rk3288_reset
339 	},
340 	{
341 		"rockchip,rk3308-cru", NULL, 1, rk3308_init,
342 		rk3308_enable, rk3308_get_frequency,
343 		rk3308_set_frequency, rk3308_set_parent,
344 		rk3308_reset
345 	},
346 	{
347 		"rockchip,rk3328-cru", NULL, 1, rk3328_init,
348 		rk3328_enable, rk3328_get_frequency,
349 		rk3328_set_frequency, rk3328_set_parent,
350 		rk3328_reset
351 	},
352 	{
353 		"rockchip,rk3399-cru", NULL, 1, rk3399_init,
354 		rk3399_enable, rk3399_get_frequency,
355 		rk3399_set_frequency, rk3399_set_parent,
356 		rk3399_reset
357 	},
358 	{
359 		"rockchip,rk3399-pmucru", NULL, 1, rk3399_pmu_init,
360 		rk3399_pmu_enable, rk3399_pmu_get_frequency,
361 		rk3399_pmu_set_frequency, NULL,
362 		rk3399_pmu_reset
363 	},
364 	{
365 		"rockchip,rk3568-cru", "CRU", 1, rk3568_init,
366 		rk3568_enable, rk3568_get_frequency,
367 		rk3568_set_frequency, rk3568_set_parent,
368 		rk3568_reset
369 	},
370 	{
371 		"rockchip,rk3568-pmucru", "PMUCRU", 1, rk3568_pmu_init,
372 		rk3568_pmu_enable, rk3568_pmu_get_frequency,
373 		rk3568_pmu_set_frequency, NULL,
374 		rk3568_pmu_reset
375 	},
376 	{
377 		"rockchip,rk3588-cru", NULL, 1, rk3588_init,
378 		rk3588_enable, rk3588_get_frequency,
379 		rk3588_set_frequency, NULL,
380 		rk3588_reset
381 	},
382 };
383 
384 int
rkclock_match(struct device * parent,void * match,void * aux)385 rkclock_match(struct device *parent, void *match, void *aux)
386 {
387 	struct fdt_attach_args *faa = aux;
388 	int i;
389 
390 	for (i = 0; i < nitems(rkclock_compat); i++) {
391 		if (OF_is_compatible(faa->fa_node, rkclock_compat[i].compat))
392 			return 10;
393 	}
394 
395 	return 0;
396 }
397 
398 void
rkclock_attach(struct device * parent,struct device * self,void * aux)399 rkclock_attach(struct device *parent, struct device *self, void *aux)
400 {
401 	struct rkclock_softc *sc = (struct rkclock_softc *)self;
402 	struct fdt_attach_args *faa = aux;
403 	uint32_t grf;
404 	int i;
405 
406 	if (faa->fa_nreg < 1) {
407 		printf(": no registers\n");
408 		return;
409 	}
410 
411 	sc->sc_iot = faa->fa_iot;
412 	if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr,
413 	    faa->fa_reg[0].size, 0, &sc->sc_ioh)) {
414 		printf(": can't map registers\n");
415 		return;
416 	}
417 
418 	grf = OF_getpropint(faa->fa_node, "rockchip,grf", 0);
419 	sc->sc_grf = regmap_byphandle(grf);
420 
421 	sc->sc_phandle = OF_getpropint(faa->fa_node, "phandle", 0);
422 
423 	for (i = 0; i < nitems(rkclock_compat); i++) {
424 		if (OF_is_compatible(faa->fa_node, rkclock_compat[i].compat)) {
425 			break;
426 		}
427 	}
428 	KASSERT(i < nitems(rkclock_compat));
429 
430 	if (rkclock_compat[i].name != NULL)
431 		printf(": %s", rkclock_compat[i].name);
432 
433 	printf("\n");
434 
435 	if (rkclock_compat[i].init)
436 		rkclock_compat[i].init(sc);
437 
438 	sc->sc_cd.cd_node = faa->fa_node;
439 	sc->sc_cd.cd_cookie = sc;
440 	sc->sc_cd.cd_enable = rkclock_compat[i].enable;
441 	sc->sc_cd.cd_get_frequency = rkclock_compat[i].get_frequency;
442 	sc->sc_cd.cd_set_frequency = rkclock_compat[i].set_frequency;
443 	sc->sc_cd.cd_set_parent = rkclock_compat[i].set_parent;
444 	clock_register(&sc->sc_cd);
445 
446 	sc->sc_rd.rd_node = faa->fa_node;
447 	sc->sc_rd.rd_cookie = sc;
448 	sc->sc_rd.rd_reset = rkclock_compat[i].reset;
449 	reset_register(&sc->sc_rd);
450 
451 	if (rkclock_compat[i].assign)
452 		clock_set_assigned(faa->fa_node);
453 }
454 
455 const struct rkclock *
rkclock_lookup(struct rkclock_softc * sc,uint32_t idx)456 rkclock_lookup(struct rkclock_softc *sc, uint32_t idx)
457 {
458 	const struct rkclock *clk;
459 
460 	for (clk = sc->sc_clocks; clk->idx; clk++) {
461 		if (clk->idx == idx)
462 			return clk;
463 	}
464 
465 	return NULL;
466 }
467 
468 uint32_t
rkclock_external_frequency(const char * name)469 rkclock_external_frequency(const char *name)
470 {
471 	char buf[64] = {};
472 	int len, node;
473 
474 	/*
475 	 * Hunt through the device tree to find a fixed-rate clock
476 	 * that has the requested clock output signal name.  This may
477 	 * be too simple.
478 	 */
479 	node = OF_peer(0);
480 	for (node = OF_child(node); node != 0; node = OF_peer(node)) {
481 		len = OF_getproplen(node, "clock-output-names");
482 		if (len <= 0 || len > sizeof(buf))
483 			continue;
484 		OF_getprop(node, "clock-output-names", buf, sizeof(buf));
485 		if (strcmp(buf, name) != 0)
486 			continue;
487 		if (OF_is_compatible(node, "fixed-clock"))
488 			return OF_getpropint(node, "clock-frequency", 0);
489 	}
490 
491 	return 0;
492 }
493 
494 uint32_t
rkclock_div_con(struct rkclock_softc * sc,const struct rkclock * clk,uint32_t mux,uint32_t freq)495 rkclock_div_con(struct rkclock_softc *sc, const struct rkclock *clk,
496     uint32_t mux, uint32_t freq)
497 {
498 	uint32_t parent_freq, div, div_con, max_div_con;
499 	uint32_t idx = clk->parents[mux];
500 
501 	/* Derive maximum value from mask. */
502 	max_div_con = clk->div_mask >> (ffs(clk->div_mask) - 1);
503 
504 	parent_freq = sc->sc_cd.cd_get_frequency(sc, &idx);
505 	div = (parent_freq + freq - 1) / freq;
506 	div_con = (div > 0 ? div - 1 : 0);
507 	return (div_con < max_div_con) ? div_con : max_div_con;
508 }
509 
510 uint32_t
rkclock_freq(struct rkclock_softc * sc,const struct rkclock * clk,uint32_t mux,uint32_t freq)511 rkclock_freq(struct rkclock_softc *sc, const struct rkclock *clk,
512     uint32_t mux, uint32_t freq)
513 {
514 	uint32_t parent_freq, div_con;
515 	uint32_t idx = clk->parents[mux];
516 
517 	parent_freq = sc->sc_cd.cd_get_frequency(sc, &idx);
518 	div_con = rkclock_div_con(sc, clk, mux, freq);
519 	return parent_freq / (div_con + 1);
520 }
521 
522 uint32_t
rkclock_get_frequency(struct rkclock_softc * sc,uint32_t idx)523 rkclock_get_frequency(struct rkclock_softc *sc, uint32_t idx)
524 {
525 	const struct rkclock *clk;
526 	uint32_t reg, mux, div_con;
527 	int shift;
528 
529 	clk = rkclock_lookup(sc, idx);
530 	if (clk == NULL) {
531 		printf("%s(%s, %u)\n", __func__, sc->sc_dev.dv_xname, idx);
532 		return 0;
533 	}
534 
535 	reg = HREAD4(sc, clk->reg);
536 	shift = ffs(clk->sel_mask) - 1;
537 	if (shift == -1)
538 		mux = 0;
539 	else
540 		mux = (reg & clk->sel_mask) >> shift;
541 	shift = ffs(clk->div_mask) - 1;
542 	if (shift == -1)
543 		div_con = 0;
544 	else
545 		div_con = (reg & clk->div_mask) >> shift;
546 
547 	if (clk->parents[mux] == 0) {
548 		printf("%s: parent 0x%08x\n", __func__, idx);
549 		return 0;
550 	}
551 	idx = clk->parents[mux];
552 	return sc->sc_cd.cd_get_frequency(sc, &idx) / (div_con + 1);
553 }
554 
555 int
rkclock_set_frequency(struct rkclock_softc * sc,uint32_t idx,uint32_t freq)556 rkclock_set_frequency(struct rkclock_softc *sc, uint32_t idx, uint32_t freq)
557 {
558 	const struct rkclock *clk;
559 	uint32_t reg, mux, div_con;
560 	uint32_t best_freq, best_mux, f;
561 	uint32_t parent;
562 	int sel_shift, div_shift, i;
563 
564 	clk = rkclock_lookup(sc, idx);
565 	if (clk == NULL) {
566 		printf("%s(%s, %u, %u)\n", __func__, sc->sc_dev.dv_xname,
567 		    idx, freq);
568 		return -1;
569 	}
570 
571 	reg = HREAD4(sc, clk->reg);
572 	sel_shift = ffs(clk->sel_mask) - 1;
573 	if (sel_shift == -1)
574 		mux = sel_shift = 0;
575 	else
576 		mux = (reg & clk->sel_mask) >> sel_shift;
577 
578 	if (clk->parents[mux] == 0) {
579 		printf("%s(%s, %u, %u) parent\n", __func__,
580 		    sc->sc_dev.dv_xname, idx, freq);
581 		return 0;
582 	}
583 
584 	if (clk->flags & SET_PARENT) {
585 		parent = clk->parents[mux];
586 		sc->sc_cd.cd_set_frequency(sc, &parent, freq);
587 		if (clk->div_mask == 0)
588 			return 0;
589 	}
590 
591 	/*
592 	 * If there is no divider, pick the parent with the frequency
593 	 * closest to the target frequency.
594 	 */
595 	if (clk->div_mask == 0) {
596 		/*
597 		 * Start out with the current parent.  This prevents
598 		 * unnecessary switching to a different parent.
599 		 */
600 		parent = clk->parents[mux];
601 		best_freq = sc->sc_cd.cd_get_frequency(sc, &parent);
602 		best_mux = mux;
603 
604 		for (i = 0; i < nitems(clk->parents); i++) {
605 			if (clk->parents[i] == 0)
606 				continue;
607 			parent = clk->parents[i];
608 			f = sc->sc_cd.cd_get_frequency(sc, &parent);
609 			if ((best_freq > freq && f < best_freq) ||
610 			    (f > best_freq && f <= freq)) {
611 				best_freq = f;
612 				best_mux = i;
613 			}
614 		}
615 
616 		HWRITE4(sc, clk->reg,
617 		    clk->sel_mask << 16 | best_mux << sel_shift);
618 		return 0;
619 	}
620 
621 	/*
622 	 * Start out with the current parent.  This prevents
623 	 * unnecessary switching to a different parent.
624 	 */
625 	best_freq = rkclock_freq(sc, clk, mux, freq);
626 	best_mux = mux;
627 
628 	/*
629 	 * Find the parent that allows configuration of a frequency
630 	 * closest to the target frequency.
631 	 */
632 	if ((clk->flags & FIXED_PARENT) == 0) {
633 		for (i = 0; i < nitems(clk->parents); i++) {
634 			if (clk->parents[i] == 0)
635 				continue;
636 			f = rkclock_freq(sc, clk, i, freq);
637 			if ((best_freq > freq && f < best_freq) ||
638 			    (f > best_freq && f <= freq)) {
639 				best_freq = f;
640 				best_mux = i;
641 			}
642 		}
643 	}
644 
645 	div_con = rkclock_div_con(sc, clk, best_mux, freq);
646 	div_shift = ffs(clk->div_mask) - 1;
647 	HWRITE4(sc, clk->reg,
648 	    clk->sel_mask << 16 | best_mux << sel_shift |
649 	    clk->div_mask << 16 | div_con << div_shift);
650 	return 0;
651 }
652 
653 int
rkclock_set_parent(struct rkclock_softc * sc,uint32_t idx,uint32_t parent)654 rkclock_set_parent(struct rkclock_softc *sc, uint32_t idx, uint32_t parent)
655 {
656 	const struct rkclock *clk;
657 	uint32_t mux;
658 	int shift;
659 
660 	clk = rkclock_lookup(sc, idx);
661 	if (clk == NULL || clk->sel_mask == 0) {
662 		printf("%s: 0x%08x\n", __func__, idx);
663 		return -1;
664 	}
665 
666 	for (mux = 0; mux < nitems(clk->parents); mux++) {
667 		if (clk->parents[mux] == parent)
668 			break;
669 	}
670 	if (mux == nitems(clk->parents) || parent == 0) {
671 		printf("%s: 0x%08x parent 0x%08x\n", __func__, idx, parent);
672 		return -1;
673 	}
674 
675 	shift = ffs(clk->sel_mask) - 1;
676 	HWRITE4(sc, clk->reg, clk->sel_mask << 16 | mux << shift);
677 	return 0;
678 }
679 
680 /*
681  * Rockchip RK3288
682  */
683 
684 const struct rkclock rk3288_clocks[] = {
685 	{
686 		RK3288_CLK_SDMMC, RK3288_CRU_CLKSEL_CON(11),
687 		SEL(7, 6), DIV(5, 0),
688 		{ RK3288_PLL_CPLL, RK3288_PLL_GPLL, RK3288_XIN24M }
689 	}
690 };
691 
692 void
rk3288_init(struct rkclock_softc * sc)693 rk3288_init(struct rkclock_softc *sc)
694 {
695 	int node;
696 
697 	/*
698 	 * Since the hardware comes up with a really conservative CPU
699 	 * clock frequency, and U-Boot doesn't set it to a more
700 	 * reasonable default, try to do so here.  These defaults were
701 	 * chosen assuming that the CPU voltage is at least 1.1 V.
702 	 * Only do this on the Tinker-RK3288 for now where this is
703 	 * likely to be true given the default voltages for the
704 	 * regulators on that board.
705 	 */
706 	node = OF_finddevice("/");
707 	if (OF_is_compatible(node, "rockchip,rk3288-tinker")) {
708 		uint32_t idx;
709 
710 		/* Run at 1.2 GHz. */
711 		idx = RK3288_ARMCLK;
712 		rk3288_set_frequency(sc, &idx, 1200000000);
713 	}
714 
715 	sc->sc_clocks = rk3288_clocks;
716 }
717 
718 uint32_t
rk3288_get_pll(struct rkclock_softc * sc,bus_size_t base)719 rk3288_get_pll(struct rkclock_softc *sc, bus_size_t base)
720 {
721 	uint32_t clkod, clkr, clkf;
722 	uint32_t reg;
723 
724 	reg = HREAD4(sc, base);
725 	clkod = (reg & RK3288_CRU_PLL_CLKOD_MASK) >>
726 	    RK3288_CRU_PLL_CLKOD_SHIFT;
727 	clkr = (reg & RK3288_CRU_PLL_CLKR_MASK) >>
728 	    RK3288_CRU_PLL_CLKR_SHIFT;
729 	reg = HREAD4(sc, base + 4);
730 	clkf = (reg & RK3288_CRU_PLL_CLKF_MASK) >>
731 	    RK3288_CRU_PLL_CLKF_SHIFT;
732 	return 24000000ULL * (clkf + 1) / (clkr + 1) / (clkod + 1);
733 }
734 
735 int
rk3288_set_pll(struct rkclock_softc * sc,bus_size_t base,uint32_t freq)736 rk3288_set_pll(struct rkclock_softc *sc, bus_size_t base, uint32_t freq)
737 {
738 	int shift = 4 * (base / RK3288_CRU_CPLL_CON(0));
739 	uint32_t no, nr, nf;
740 
741 	/*
742 	 * It is not clear whether all combinations of the clock
743 	 * dividers result in a stable clock.  Therefore this function
744 	 * only supports a limited set of PLL clock rates.  For now
745 	 * this set covers all the CPU frequencies supported by the
746 	 * Linux kernel.
747 	 */
748 	switch (freq) {
749 	case 1800000000:
750 	case 1704000000:
751 	case 1608000000:
752 	case 1512000000:
753 	case 1488000000:
754 	case 1416000000:
755 	case 1200000000:
756 		nr = no = 1;
757 		break;
758 	case 1008000000:
759 	case 816000000:
760 	case 696000000:
761 	case 600000000:
762 		nr = 1; no = 2;
763 		break;
764 	case 408000000:
765 	case 312000000:
766 		nr = 1; no = 4;
767 		break;
768 	case 216000000:
769 	case 126000000:
770 		nr = 1; no = 8;
771 		break;
772 	default:
773 		printf("%s: %u Hz\n", __func__, freq);
774 		return -1;
775 	}
776 
777 	/* Calculate feedback divider. */
778 	nf = freq * nr * no / 24000000;
779 
780 	/*
781 	 * Select slow mode to guarantee a stable clock while we're
782 	 * adjusting the PLL.
783 	 */
784 	HWRITE4(sc, RK3288_CRU_MODE_CON,
785 	    (RK3288_CRU_MODE_PLL_WORK_MODE_MASK << 16 |
786 	     RK3288_CRU_MODE_PLL_WORK_MODE_SLOW) << shift);
787 
788 	/* Assert reset. */
789 	HWRITE4(sc, base + 0x000c,
790 	    RK3288_CRU_PLL_RESET << 16 | RK3288_CRU_PLL_RESET);
791 
792 	/* Set PLL rate. */
793 	HWRITE4(sc, base + 0x0000,
794 	    RK3288_CRU_PLL_CLKR_MASK << 16 |
795 	    (nr - 1) << RK3288_CRU_PLL_CLKR_SHIFT |
796 	    RK3288_CRU_PLL_CLKOD_MASK << 16 |
797 	    (no - 1) << RK3288_CRU_PLL_CLKOD_SHIFT);
798 	HWRITE4(sc, base + 0x0004,
799 	    RK3288_CRU_PLL_CLKF_MASK << 16 |
800 	    (nf - 1) << RK3288_CRU_PLL_CLKF_SHIFT);
801 
802 	/* Deassert reset and wait. */
803 	HWRITE4(sc, base + 0x000c,
804 	    RK3288_CRU_PLL_RESET << 16);
805 	delay((nr * 500 / 24) + 1);
806 
807 	/* Switch back to normal mode. */
808 	HWRITE4(sc, RK3288_CRU_MODE_CON,
809 	    (RK3288_CRU_MODE_PLL_WORK_MODE_MASK << 16 |
810 	     RK3288_CRU_MODE_PLL_WORK_MODE_NORMAL) << shift);
811 
812 	return 0;
813 }
814 
815 uint32_t
rk3288_get_frequency(void * cookie,uint32_t * cells)816 rk3288_get_frequency(void *cookie, uint32_t *cells)
817 {
818 	struct rkclock_softc *sc = cookie;
819 	uint32_t idx = cells[0];
820 	uint32_t reg, mux, div_con, aclk_div_con;
821 
822 	switch (idx) {
823 	case RK3288_PLL_APLL:
824 		return rk3288_get_pll(sc, RK3288_CRU_APLL_CON(0));
825 	case RK3288_PLL_CPLL:
826 		return rk3288_get_pll(sc, RK3288_CRU_CPLL_CON(0));
827 	case RK3288_PLL_GPLL:
828 		return rk3288_get_pll(sc, RK3288_CRU_GPLL_CON(0));
829 	case RK3288_PLL_NPLL:
830 		return rk3288_get_pll(sc, RK3288_CRU_NPLL_CON(0));
831 	case RK3288_ARMCLK:
832 		reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(0));
833 		mux = (reg >> 15) & 0x1;
834 		div_con = (reg >> 8) & 0x1f;
835 		idx = (mux == 0) ? RK3288_PLL_APLL : RK3288_PLL_GPLL;
836 		return rk3288_get_frequency(sc, &idx) / (div_con + 1);
837 	case RK3288_XIN24M:
838 		return 24000000;
839 	case RK3288_CLK_UART0:
840 		reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(13));
841 		mux = (reg >> 8) & 0x3;
842 		div_con = reg & 0x7f;
843 		if (mux == 2)
844 			return 24000000 / (div_con + 1);
845 		break;
846 	case RK3288_CLK_UART1:
847 		reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(14));
848 		mux = (reg >> 8) & 0x3;
849 		div_con = reg & 0x7f;
850 		if (mux == 2)
851 			return 24000000 / (div_con + 1);
852 		break;
853 	case RK3288_CLK_UART2:
854 		reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(15));
855 		mux = (reg >> 8) & 0x3;
856 		div_con = reg & 0x7f;
857 		if (mux == 2)
858 			return 24000000 / (div_con + 1);
859 		break;
860 	case RK3288_CLK_UART3:
861 		reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(16));
862 		mux = (reg >> 8) & 0x3;
863 		div_con = reg & 0x7f;
864 		if (mux == 2)
865 			return 24000000 / (div_con + 1);
866 		break;
867 	case RK3288_CLK_UART4:
868 		reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(3));
869 		mux = (reg >> 8) & 0x3;
870 		div_con = reg & 0x7f;
871 		if (mux == 2)
872 			return 24000000 / (div_con + 1);
873 		break;
874 	case RK3288_CLK_MAC:
875 		reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(21));
876 		if (reg & 0x10)
877 			return 125000000;
878 		mux = (reg >> 0) & 0x3;
879 		div_con = (reg >> 8) & 0x1f;
880 		switch (mux) {
881 		case 0:
882 			idx = RK3288_PLL_NPLL;
883 			break;
884 		case 1:
885 			idx = RK3288_PLL_CPLL;
886 			break;
887 		case 2:
888 			idx = RK3288_PLL_GPLL;
889 			break;
890 		default:
891 			return 0;
892 		}
893 		return rk3288_get_frequency(sc, &idx) / (div_con + 1);
894 	case RK3288_PCLK_I2C0:
895 	case RK3288_PCLK_I2C2:
896 		reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(1));
897 		mux = (reg >> 15) & 0x1;
898 		/* pd_bus_pclk_div_con */
899 		div_con = (reg >> 12) & 0x7;
900 		if (mux == 1)
901 			idx = RK3288_PLL_GPLL;
902 		else
903 			idx = RK3288_PLL_CPLL;
904 		return rk3288_get_frequency(sc, &idx) / (div_con + 1);
905 	case RK3288_PCLK_I2C1:
906 	case RK3288_PCLK_I2C3:
907 	case RK3288_PCLK_I2C4:
908 	case RK3288_PCLK_I2C5:
909 		reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(10));
910 		mux = (reg >> 15) & 0x1;
911 		/* peri_pclk_div_con */
912 		div_con = (reg >> 12) & 0x3;
913 		/* peri_aclk_div_con */
914 		aclk_div_con = reg & 0xf;
915 		if (mux == 1)
916 			idx = RK3288_PLL_GPLL;
917 		else
918 			idx = RK3288_PLL_CPLL;
919 		return (rk3288_get_frequency(sc, &idx) / (aclk_div_con + 1)) >>
920 		    div_con;
921 	default:
922 		break;
923 	}
924 
925 	return rkclock_get_frequency(sc, idx);
926 }
927 
928 int
rk3288_set_frequency(void * cookie,uint32_t * cells,uint32_t freq)929 rk3288_set_frequency(void *cookie, uint32_t *cells, uint32_t freq)
930 {
931 	struct rkclock_softc *sc = cookie;
932 	uint32_t idx = cells[0];
933 	int error;
934 
935 	switch (idx) {
936 	case RK3288_PLL_APLL:
937 		return rk3288_set_pll(sc, RK3288_CRU_APLL_CON(0), freq);
938 	case RK3288_ARMCLK:
939 		idx = RK3288_PLL_APLL;
940 		error = rk3288_set_frequency(sc, &idx, freq);
941 		if (error == 0) {
942 			HWRITE4(sc, RK3288_CRU_CLKSEL_CON(0),
943 			    ((1 << 15) | (0x1f << 8)) << 16);
944 		}
945 		return error;
946 	default:
947 		break;
948 	}
949 
950 	return rkclock_set_frequency(sc, idx, freq);
951 }
952 
953 void
rk3288_enable(void * cookie,uint32_t * cells,int on)954 rk3288_enable(void *cookie, uint32_t *cells, int on)
955 {
956 	uint32_t idx = cells[0];
957 
958 	switch (idx) {
959 	case RK3288_CLK_SDMMC:
960 	case RK3288_CLK_TSADC:
961 	case RK3288_CLK_UART0:
962 	case RK3288_CLK_UART1:
963 	case RK3288_CLK_UART2:
964 	case RK3288_CLK_UART3:
965 	case RK3288_CLK_UART4:
966 	case RK3288_CLK_MAC_RX:
967 	case RK3288_CLK_MAC_TX:
968 	case RK3288_CLK_SDMMC_DRV:
969 	case RK3288_CLK_SDMMC_SAMPLE:
970 	case RK3288_CLK_MAC:
971 	case RK3288_ACLK_GMAC:
972 	case RK3288_PCLK_GMAC:
973 	case RK3288_PCLK_I2C0:
974 	case RK3288_PCLK_I2C1:
975 	case RK3288_PCLK_I2C2:
976 	case RK3288_PCLK_I2C3:
977 	case RK3288_PCLK_I2C4:
978 	case RK3288_PCLK_I2C5:
979 	case RK3288_PCLK_TSADC:
980 	case RK3288_HCLK_HOST0:
981 	case RK3288_HCLK_SDMMC:
982 		/* Enabled by default. */
983 		break;
984 	default:
985 		printf("%s: 0x%08x\n", __func__, idx);
986 		break;
987 	}
988 }
989 
990 void
rk3288_reset(void * cookie,uint32_t * cells,int on)991 rk3288_reset(void *cookie, uint32_t *cells, int on)
992 {
993 	struct rkclock_softc *sc = cookie;
994 	uint32_t idx = cells[0];
995 	uint32_t mask = (1 << (idx % 16));
996 
997 	HWRITE4(sc, RK3288_CRU_SOFTRST_CON(idx / 16),
998 	    mask << 16 | (on ? mask : 0));
999 }
1000 
1001 /*
1002  * Rockchip RK3308
1003  */
1004 
1005 const struct rkclock rk3308_clocks[] = {
1006 	{
1007 		RK3308_CLK_RTC32K, RK3308_CRU_CLKSEL_CON(2),
1008 		SEL(10, 9), 0,
1009 		{ RK3308_PLL_VPLL0, RK3308_PLL_VPLL1 }
1010 	},
1011 	{
1012 		RK3308_CLK_UART0, RK3308_CRU_CLKSEL_CON(10),
1013 		SEL(15, 13), DIV(4, 0),
1014 		{ RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1,
1015 		  RK3308_USB480M, RK3308_XIN24M }
1016 	},
1017 	{
1018 		RK3308_CLK_UART1, RK3308_CRU_CLKSEL_CON(13),
1019 		SEL(15, 13), DIV(4, 0),
1020 		{ RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1,
1021 		  RK3308_USB480M, RK3308_XIN24M }
1022 	},
1023 	{
1024 		RK3308_CLK_UART2, RK3308_CRU_CLKSEL_CON(16),
1025 		SEL(15, 13), DIV(4, 0),
1026 		{ RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1,
1027 		  RK3308_USB480M, RK3308_XIN24M }
1028 	},
1029 	{
1030 		RK3308_CLK_UART3, RK3308_CRU_CLKSEL_CON(19),
1031 		SEL(15, 13), DIV(4, 0),
1032 		{ RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1,
1033 		  RK3308_USB480M, RK3308_XIN24M }
1034 	},
1035 	{
1036 		RK3308_CLK_UART4, RK3308_CRU_CLKSEL_CON(22),
1037 		SEL(15, 13), DIV(4, 0),
1038 		{ RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1,
1039 		  RK3308_USB480M, RK3308_XIN24M }
1040 	},
1041 	{
1042 		RK3308_CLK_PWM0, RK3308_CRU_CLKSEL_CON(29),
1043 		SEL(15, 14), DIV(6, 0),
1044 		{ RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_XIN24M }
1045 	},
1046 	{
1047 		RK3308_CLK_SPI0, RK3308_CRU_CLKSEL_CON(30),
1048 		SEL(15, 14), DIV(6, 0),
1049 		{ RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_XIN24M }
1050 	},
1051 	{
1052 		RK3308_CLK_SPI1, RK3308_CRU_CLKSEL_CON(31),
1053 		SEL(15, 14), DIV(6, 0),
1054 		{ RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_XIN24M }
1055 	},
1056 	{
1057 		RK3308_CLK_SPI2, RK3308_CRU_CLKSEL_CON(32),
1058 		SEL(15, 14), DIV(6, 0),
1059 		{ RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_XIN24M }
1060 	},
1061 	{
1062 		RK3308_CLK_TSADC, RK3308_CRU_CLKSEL_CON(33),
1063 		0, DIV(10, 0),
1064 		{ RK3308_XIN24M }
1065 	},
1066 	{
1067 		RK3308_CLK_SARADC, RK3308_CRU_CLKSEL_CON(34),
1068 		0, DIV(10, 0),
1069 		{ RK3308_XIN24M }
1070 	},
1071 	{
1072 		RK3308_CLK_CRYPTO, RK3308_CRU_CLKSEL_CON(7),
1073 		SEL(7, 6), DIV(4, 0),
1074 		{ RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1, 0 }
1075 	},
1076 	{
1077 		RK3308_CLK_CRYPTO_APK, RK3308_CRU_CLKSEL_CON(7),
1078 		SEL(15, 14), DIV(12, 8),
1079 		{ RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1, 0 }
1080 	},
1081 	{
1082 		RK3308_CLK_SDMMC, RK3308_CRU_CLKSEL_CON(39),
1083 		SEL(9, 8), DIV(7, 0),
1084 		{ RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1,
1085 		  RK3308_XIN24M }
1086 	},
1087 	{
1088 		RK3308_CLK_SDIO, RK3308_CRU_CLKSEL_CON(40),
1089 		SEL(9, 8), DIV(7, 0),
1090 		{ RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1,
1091 		  RK3308_XIN24M }
1092 	},
1093 	{
1094 		RK3308_CLK_EMMC, RK3308_CRU_CLKSEL_CON(41),
1095 		SEL(9, 8), DIV(7, 0),
1096 		{ RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1,
1097 		  RK3308_XIN24M }
1098 	},
1099 	{
1100 		RK3308_CLK_MAC_SRC, RK3308_CRU_CLKSEL_CON(43),
1101 		SEL(7, 6), DIV(4, 0),
1102 		{ RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1, 0 }
1103 	},
1104 	{
1105 		RK3308_CLK_MAC, RK3308_CRU_CLKSEL_CON(43),
1106 		SEL(14, 13), 0,
1107 		{ RK3308_CLK_MAC_SRC, 0 },
1108 		SET_PARENT
1109 	},
1110 	{
1111 		RK3308_ACLK_PERI_SRC, RK3308_CRU_CLKSEL_CON(36),
1112 		SEL(7, 6), 0,
1113 		{ RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1, 0 }
1114 	},
1115 	{
1116 		RK3308_PCLK_PERI, RK3308_CRU_CLKSEL_CON(37),
1117 		0, DIV(12, 8),
1118 		{ RK3308_ACLK_PERI_SRC }
1119 	},
1120 	{
1121 		RK3308_PCLK_MAC, 0, 0, 0,
1122 		{ RK3308_PCLK_PERI }
1123 	},
1124 
1125 	{
1126 		/* Sentinel */
1127 	}
1128 };
1129 
1130 void
rk3308_init(struct rkclock_softc * sc)1131 rk3308_init(struct rkclock_softc *sc)
1132 {
1133 	int i;
1134 
1135 	/* The code below assumes all clocks are enabled.  Check this!. */
1136 	for (i = 0; i <= 14; i++) {
1137 		if (HREAD4(sc, RK3308_CRU_CLKGATE_CON(i)) != 0x00000000) {
1138 			printf("CRU_CLKGATE_CON%d: 0x%08x\n", i,
1139 			    HREAD4(sc, RK3308_CRU_CLKGATE_CON(i)));
1140 		}
1141 	}
1142 	sc->sc_clocks = rk3308_clocks;
1143 }
1144 
1145 uint32_t
rk3308_armclk_parent(uint32_t mux)1146 rk3308_armclk_parent(uint32_t mux)
1147 {
1148 	switch (mux) {
1149 	case 0:
1150 		return RK3308_PLL_APLL;
1151 	case 1:
1152 		return RK3308_PLL_VPLL0;
1153 	case 2:
1154 		return RK3308_PLL_VPLL1;
1155 	}
1156 
1157 	return 0;
1158 }
1159 
1160 uint32_t
rk3308_get_armclk(struct rkclock_softc * sc)1161 rk3308_get_armclk(struct rkclock_softc *sc)
1162 {
1163 	uint32_t reg, mux, div_con;
1164 	uint32_t idx;
1165 
1166 	reg = HREAD4(sc, RK3308_CRU_CLKSEL_CON(0));
1167 	mux = (reg & RK3308_CRU_CORE_CLK_PLL_SEL_MASK) >>
1168 	    RK3308_CRU_CORE_CLK_PLL_SEL_SHIFT;
1169 	div_con = (reg & RK3308_CRU_CLK_CORE_DIV_CON_MASK) >>
1170 	    RK3308_CRU_CLK_CORE_DIV_CON_SHIFT;
1171 	idx = rk3308_armclk_parent(mux);
1172 
1173 	return rk3308_get_frequency(sc, &idx) / (div_con + 1);
1174 }
1175 
1176 int
rk3308_set_armclk(struct rkclock_softc * sc,uint32_t freq)1177 rk3308_set_armclk(struct rkclock_softc *sc, uint32_t freq)
1178 {
1179 	uint32_t reg, mux;
1180 	uint32_t old_freq, div;
1181 	uint32_t idx;
1182 
1183 	old_freq = rk3308_get_armclk(sc);
1184 	if (freq == old_freq)
1185 		return 0;
1186 
1187 	reg = HREAD4(sc, RK3308_CRU_CLKSEL_CON(0));
1188 	mux = (reg & RK3308_CRU_CORE_CLK_PLL_SEL_MASK) >>
1189 	    RK3308_CRU_CORE_CLK_PLL_SEL_SHIFT;
1190 
1191 	/* Keep the pclk_dbg clock at or below 300 MHz. */
1192 	div = 1;
1193 	while (freq / (div + 1) > 300000000)
1194 		div++;
1195 	/* and make sure we use an odd divider. */
1196 	if ((div % 2) == 0)
1197 		div++;
1198 
1199 	/* When ramping up, set clock dividers first. */
1200 	if (freq > old_freq) {
1201 		HWRITE4(sc, RK3308_CRU_CLKSEL_CON(0),
1202 		    RK3308_CRU_CLK_CORE_DIV_CON_MASK << 16 |
1203 		    0 << RK3308_CRU_CLK_CORE_DIV_CON_SHIFT |
1204 		    RK3308_CRU_ACLK_CORE_DIV_CON_MASK << 16 |
1205 		    1 << RK3308_CRU_ACLK_CORE_DIV_CON_SHIFT |
1206 		    RK3308_CRU_CLK_CORE_DBG_DIV_CON_MASK << 16 |
1207 		    div << RK3308_CRU_CLK_CORE_DBG_DIV_CON_SHIFT);
1208 	}
1209 
1210 	/* We always use VPLL1 and force the switch below if needed. */
1211 	idx = RK3308_PLL_VPLL1;
1212 	rk3308_set_frequency(sc, &idx, freq);
1213 
1214 	/* When ramping down, set clock dividers last. */
1215 	if (freq < old_freq || mux != 2) {
1216 		HWRITE4(sc, RK3308_CRU_CLKSEL_CON(0),
1217 		    RK3308_CRU_CORE_CLK_PLL_SEL_MASK << 16 |
1218 		    2 << RK3308_CRU_CORE_CLK_PLL_SEL_SHIFT |
1219 		    RK3308_CRU_CLK_CORE_DIV_CON_MASK << 16 |
1220 		    0 << RK3308_CRU_CLK_CORE_DIV_CON_SHIFT |
1221 		    RK3308_CRU_ACLK_CORE_DIV_CON_MASK << 16 |
1222 		    1 << RK3308_CRU_ACLK_CORE_DIV_CON_SHIFT |
1223 		    RK3308_CRU_CLK_CORE_DBG_DIV_CON_MASK << 16 |
1224 		    div << RK3308_CRU_CLK_CORE_DBG_DIV_CON_SHIFT);
1225 	}
1226 
1227 	return 0;
1228 }
1229 
1230 uint32_t
rk3308_get_pll(struct rkclock_softc * sc,bus_size_t base)1231 rk3308_get_pll(struct rkclock_softc *sc, bus_size_t base)
1232 {
1233 	uint32_t fbdiv, postdiv1, postdiv2, refdiv;
1234 	uint32_t dsmpd, fracdiv;
1235 	uint64_t frac = 0;
1236 	uint32_t reg;
1237 
1238 	reg = HREAD4(sc, base + 0x0000);
1239 	postdiv1 = (reg & RK3308_CRU_PLL_POSTDIV1_MASK) >>
1240 	    RK3308_CRU_PLL_POSTDIV1_SHIFT;
1241 	fbdiv = (reg & RK3308_CRU_PLL_FBDIV_MASK) >>
1242 	    RK3308_CRU_PLL_FBDIV_SHIFT;
1243 	reg = HREAD4(sc, base + 0x0004);
1244 	dsmpd = (reg & RK3308_CRU_PLL_DSMPD);
1245 	postdiv2 = (reg & RK3308_CRU_PLL_POSTDIV2_MASK) >>
1246 	    RK3308_CRU_PLL_POSTDIV2_SHIFT;
1247 	refdiv = (reg & RK3308_CRU_PLL_REFDIV_MASK) >>
1248 	    RK3308_CRU_PLL_REFDIV_SHIFT;
1249 	reg = HREAD4(sc, base + 0x0008);
1250 	fracdiv = (reg & RK3308_CRU_PLL_FRACDIV_MASK) >>
1251 	    RK3308_CRU_PLL_FRACDIV_SHIFT;
1252 
1253 	if (dsmpd == 0)
1254 		frac = (24000000ULL * fracdiv / refdiv) >> 24;
1255 	return ((24000000ULL * fbdiv / refdiv) + frac) / postdiv1 / postdiv2;
1256 }
1257 
1258 int
rk3308_set_pll(struct rkclock_softc * sc,bus_size_t base,uint32_t freq)1259 rk3308_set_pll(struct rkclock_softc *sc, bus_size_t base, uint32_t freq)
1260 {
1261 	uint32_t fbdiv, postdiv1, postdiv2, refdiv;
1262 	int mode_shift = -1;
1263 
1264 	switch (base) {
1265 	case RK3308_CRU_APLL_CON(0):
1266 		mode_shift = 0;
1267 		break;
1268 	case RK3308_CRU_DPLL_CON(0):
1269 		mode_shift = 2;
1270 		break;
1271 	case RK3308_CRU_VPLL0_CON(0):
1272 		mode_shift = 4;
1273 		break;
1274 	case RK3308_CRU_VPLL1_CON(0):
1275 		mode_shift = 6;
1276 		break;
1277 	}
1278 	KASSERT(mode_shift != -1);
1279 
1280 	/*
1281 	 * It is not clear whether all combinations of the clock
1282 	 * dividers result in a stable clock.  Therefore this function
1283 	 * only supports a limited set of PLL clock rates.  For now
1284 	 * this set covers all the CPU frequencies supported by the
1285 	 * Linux kernel.
1286 	 */
1287 	switch (freq) {
1288 	case 1608000000U:
1289 	case 1584000000U:
1290 	case 1560000000U:
1291 	case 1536000000U:
1292 	case 1512000000U:
1293 	case 1488000000U:
1294 	case 1464000000U:
1295 	case 1440000000U:
1296 	case 1416000000U:
1297 	case 1392000000U:
1298 	case 1368000000U:
1299 	case 1344000000U:
1300 	case 1320000000U:
1301 	case 1296000000U:
1302 	case 1272000000U:
1303 	case 1248000000U:
1304 	case 1200000000U:
1305 	case 1104000000U:
1306 		postdiv1 = postdiv2 = refdiv = 1;
1307 		break;
1308 	case 1188000000U:
1309 		refdiv = 2; postdiv1 = postdiv2 = 1;
1310 		break;
1311 	case 1100000000U:
1312 		refdiv = 12; postdiv1 = postdiv2 = 1;
1313 		break;
1314 	case 1000000000U:
1315 		refdiv = 6; postdiv1 = postdiv2 = 1;
1316 		break;
1317 	case 1008000000U:
1318 	case 984000000U:
1319 	case 960000000U:
1320 	case 936000000U:
1321 	case 912000000U:
1322 	case 888000000U:
1323 	case 864000000U:
1324 	case 840000000U:
1325 	case 816000000U:
1326 	case 696000000U:
1327 	case 624000000U:
1328 		postdiv1 = 2; postdiv2 = refdiv = 1;
1329 		break;
1330 	case 900000000U:
1331 		refdiv = 4; postdiv1 = 2; postdiv2 = 1;
1332 		break;
1333 	case 800000000U:
1334 	case 700000000U:
1335 	case 500000000U:
1336 		refdiv = 6; postdiv1 = 2; postdiv2 = 1;
1337 		break;
1338 	case 600000000U:
1339 	case 504000000U:
1340 		postdiv1 = 3; postdiv2 = refdiv = 1;
1341 		break;
1342 	case 594000000U:
1343 		refdiv = 2; postdiv1 = 2; postdiv2 = 1;
1344 		break;
1345 	case 408000000U:
1346 	case 312000000U:
1347 		postdiv1 = postdiv2 = 2; refdiv = 1;
1348 		break;
1349 	case 216000000U:
1350 		postdiv1 = 4; postdiv2 = 2; refdiv = 1;
1351 		break;
1352 	case 96000000U:
1353 		postdiv1 = postdiv2 = 4; refdiv = 1;
1354 		break;
1355 	default:
1356 		printf("%s: %u Hz\n", __func__, freq);
1357 		return -1;
1358 	}
1359 
1360 	/* Calculate feedback divider. */
1361 	fbdiv = freq * postdiv1 * postdiv2 * refdiv / 24000000;
1362 
1363 	/*
1364 	 * Select slow mode to guarantee a stable clock while we're
1365 	 * adjusting the PLL.
1366 	 */
1367 	HWRITE4(sc, RK3308_CRU_CRU_MODE,
1368 	   (RK3308_CRU_CRU_MODE_MASK << 16 |
1369 	   RK3308_CRU_CRU_MODE_SLOW) << mode_shift);
1370 
1371 	/* Set PLL rate. */
1372 	HWRITE4(sc, base + 0x0000,
1373 	    RK3308_CRU_PLL_POSTDIV1_MASK << 16 |
1374 	    postdiv1 << RK3308_CRU_PLL_POSTDIV1_SHIFT |
1375 	    RK3308_CRU_PLL_FBDIV_MASK << 16 |
1376 	    fbdiv << RK3308_CRU_PLL_FBDIV_SHIFT);
1377 	HWRITE4(sc, base + 0x0004,
1378 	    RK3308_CRU_PLL_DSMPD << 16 | RK3308_CRU_PLL_DSMPD |
1379 	    RK3308_CRU_PLL_POSTDIV2_MASK << 16 |
1380 	    postdiv2 << RK3308_CRU_PLL_POSTDIV2_SHIFT |
1381 	    RK3308_CRU_PLL_REFDIV_MASK << 16 |
1382 	    refdiv << RK3308_CRU_PLL_REFDIV_SHIFT);
1383 
1384 	/* Wait for PLL to stabilize. */
1385 	while ((HREAD4(sc, base + 0x0004) & RK3308_CRU_PLL_PLL_LOCK) == 0)
1386 		delay(10);
1387 
1388 	/* Switch back to normal mode. */
1389 	HWRITE4(sc, RK3308_CRU_CRU_MODE,
1390 	   (RK3308_CRU_CRU_MODE_MASK << 16 |
1391 	   RK3308_CRU_CRU_MODE_NORMAL) << mode_shift);
1392 
1393 	return 0;
1394 }
1395 
1396 uint32_t
rk3308_get_rtc32k(struct rkclock_softc * sc)1397 rk3308_get_rtc32k(struct rkclock_softc *sc)
1398 {
1399 	uint32_t reg, mux, pll, div_con;
1400 
1401 	reg = HREAD4(sc, RK3308_CRU_CLKSEL_CON(2));
1402 	mux = (reg & 0x300) >> 8;
1403 	if (mux != 3) {
1404 		printf("%s: RTC32K not using clk_32k_div\n", __func__);
1405 		return 0;
1406 	}
1407 
1408 	if ((reg >> 10) & 1)
1409 		pll = RK3308_PLL_VPLL1;
1410 	else
1411 		pll = RK3308_PLL_VPLL0;
1412 
1413 	div_con = HREAD4(sc, RK3308_CRU_CLKSEL_CON(4)) & 0xffff;
1414 	return rk3308_get_frequency(sc, &pll) / (div_con + 1);
1415 }
1416 
1417 int
rk3308_set_rtc32k(struct rkclock_softc * sc,uint32_t freq)1418 rk3308_set_rtc32k(struct rkclock_softc *sc, uint32_t freq)
1419 {
1420 	const struct rkclock *clk;
1421 	uint32_t vpll0_freq, vpll1_freq, mux, div_con;
1422 
1423 	clk = rkclock_lookup(sc, RK3308_CLK_RTC32K);
1424 	vpll0_freq = rkclock_freq(sc, clk, 0, freq);
1425 	vpll1_freq = rkclock_freq(sc, clk, 1, freq);
1426 	mux = 0;
1427 	freq = vpll0_freq;
1428 
1429 	if ((vpll1_freq > vpll0_freq && vpll1_freq <= freq) ||
1430 	    (vpll1_freq < vpll0_freq && vpll1_freq >= freq)) {
1431 		mux = 1;
1432 		freq = vpll1_freq;
1433 	}
1434 
1435 	div_con = rkclock_div_con(sc, clk, mux, freq);
1436 	HWRITE4(sc, RK3308_CRU_CLKSEL_CON(2), 1 << 26 | (mux << 10));
1437 	HWRITE4(sc, RK3308_CRU_CLKSEL_CON(4), 0xffff0000 | div_con);
1438 	return 0;
1439 }
1440 
1441 uint32_t
rk3308_get_frequency(void * cookie,uint32_t * cells)1442 rk3308_get_frequency(void *cookie, uint32_t *cells)
1443 {
1444 	struct rkclock_softc *sc = cookie;
1445 	uint32_t idx = cells[0];
1446 
1447 	switch (idx) {
1448 	case RK3308_PLL_APLL:
1449 		return rk3308_get_pll(sc, RK3308_CRU_APLL_CON(0));
1450 	case RK3308_PLL_DPLL:
1451 		return rk3308_get_pll(sc, RK3308_CRU_DPLL_CON(0));
1452 	case RK3308_PLL_VPLL0:
1453 		return rk3308_get_pll(sc, RK3308_CRU_VPLL0_CON(0));
1454 	case RK3308_PLL_VPLL1:
1455 		return rk3308_get_pll(sc, RK3308_CRU_VPLL1_CON(0));
1456 	case RK3308_ARMCLK:
1457 		return rk3308_get_armclk(sc);
1458 	case RK3308_XIN24M:
1459 		return 24000000;
1460 	case RK3308_CLK_RTC32K:
1461 		return rk3308_get_rtc32k(sc);
1462 
1463 	/*
1464 	 * XXX The USB480M clock is external.  Returning zero here will cause
1465 	 * it to be ignored for reparenting purposes.
1466 	 */
1467 	case RK3308_USB480M:
1468 		return 0;
1469 	default:
1470 		break;
1471 	}
1472 
1473 	return rkclock_get_frequency(sc, idx);
1474 }
1475 
1476 int
rk3308_set_frequency(void * cookie,uint32_t * cells,uint32_t freq)1477 rk3308_set_frequency(void *cookie, uint32_t *cells, uint32_t freq)
1478 {
1479 	struct rkclock_softc *sc = cookie;
1480 	uint32_t idx = cells[0];
1481 
1482 	switch (idx) {
1483 	case RK3308_PLL_APLL:
1484 		return rk3308_set_pll(sc, RK3308_CRU_APLL_CON(0), freq);
1485 	case RK3308_PLL_DPLL:
1486 		return rk3308_set_pll(sc, RK3308_CRU_DPLL_CON(0), freq);
1487 	case RK3308_PLL_VPLL0:
1488 		return rk3308_set_pll(sc, RK3308_CRU_VPLL0_CON(0), freq);
1489 	case RK3308_PLL_VPLL1:
1490 		return rk3308_set_pll(sc, RK3308_CRU_VPLL1_CON(0), freq);
1491 	case RK3308_ARMCLK:
1492 		return rk3308_set_armclk(sc, freq);
1493 	case RK3308_CLK_RTC32K:
1494 		return rk3308_set_rtc32k(sc, freq);
1495 	default:
1496 		break;
1497 	}
1498 
1499 	return rkclock_set_frequency(sc, idx, freq);
1500 }
1501 
1502 
1503 int
rk3308_set_parent(void * cookie,uint32_t * cells,uint32_t * pcells)1504 rk3308_set_parent(void *cookie, uint32_t *cells, uint32_t *pcells)
1505 {
1506 	struct rkclock_softc *sc = cookie;
1507 
1508 	if (pcells[0] != sc->sc_phandle)
1509 		return -1;
1510 
1511 	return rkclock_set_parent(sc, cells[0], pcells[1]);
1512 }
1513 
1514 void
rk3308_enable(void * cookie,uint32_t * cells,int on)1515 rk3308_enable(void *cookie, uint32_t *cells, int on)
1516 {
1517 	uint32_t idx = cells[0];
1518 
1519 	/*
1520 	 * All clocks are enabled by default, so there is nothing for
1521 	 * us to do until we start disabling clocks.
1522 	 */
1523 	if (!on)
1524 		printf("%s: 0x%08x\n", __func__, idx);
1525 }
1526 
1527 void
rk3308_reset(void * cookie,uint32_t * cells,int on)1528 rk3308_reset(void *cookie, uint32_t *cells, int on)
1529 {
1530 	struct rkclock_softc *sc = cookie;
1531 	uint32_t idx = cells[0];
1532 	uint32_t mask = (1 << (idx % 16));
1533 
1534 	HWRITE4(sc, RK3308_CRU_SOFTRST_CON(idx / 16),
1535 	    mask << 16 | (on ? mask : 0));
1536 }
1537 
1538 
1539 /*
1540  * Rockchip RK3328
1541  */
1542 
1543 const struct rkclock rk3328_clocks[] = {
1544 	{
1545 		RK3328_CLK_RTC32K, RK3328_CRU_CLKSEL_CON(38),
1546 		SEL(15, 14), DIV(13, 0),
1547 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_XIN24M }
1548 	},
1549 	{
1550 		RK3328_CLK_SPI, RK3328_CRU_CLKSEL_CON(24),
1551 		SEL(7, 7), DIV(6, 0),
1552 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL }
1553 	},
1554 	{
1555 		RK3328_CLK_SDMMC, RK3328_CRU_CLKSEL_CON(30),
1556 		SEL(9, 8), DIV(7, 0),
1557 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_XIN24M,
1558 		  RK3328_USB480M }
1559 	},
1560 	{
1561 		RK3328_CLK_SDIO, RK3328_CRU_CLKSEL_CON(31),
1562 		SEL(9, 8), DIV(7, 0),
1563 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_XIN24M,
1564 		  RK3328_USB480M }
1565 	},
1566 	{
1567 		RK3328_CLK_EMMC, RK3328_CRU_CLKSEL_CON(32),
1568 		SEL(9, 8), DIV(7, 0),
1569 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_XIN24M,
1570 		  RK3328_USB480M }
1571 	},
1572 	{
1573 		RK3328_CLK_TSADC, RK3328_CRU_CLKSEL_CON(22),
1574 		0, DIV(9, 0),
1575 		{ RK3328_CLK_24M }
1576 	},
1577 	{
1578 		RK3328_CLK_UART0, RK3328_CRU_CLKSEL_CON(14),
1579 		SEL(9, 8), 0,
1580 		{ 0, 0, RK3328_XIN24M, RK3328_XIN24M }
1581 	},
1582 	{
1583 		RK3328_CLK_UART1, RK3328_CRU_CLKSEL_CON(16),
1584 		SEL(9, 8), 0,
1585 		{ 0, 0, RK3328_XIN24M, RK3328_XIN24M }
1586 	},
1587 	{
1588 		RK3328_CLK_UART2, RK3328_CRU_CLKSEL_CON(18),
1589 		SEL(9, 8), 0,
1590 		{ 0, 0, RK3328_XIN24M, RK3328_XIN24M }
1591 	},
1592 	{
1593 		RK3328_CLK_WIFI, RK3328_CRU_CLKSEL_CON(52),
1594 		SEL(7, 6), DIV(5, 0),
1595 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_USB480M }
1596 	},
1597 	{
1598 		RK3328_CLK_I2C0, RK3328_CRU_CLKSEL_CON(34),
1599 		SEL(7, 7), DIV(6, 0),
1600 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL }
1601 	},
1602 	{
1603 		RK3328_CLK_I2C1, RK3328_CRU_CLKSEL_CON(34),
1604 		SEL(15, 15), DIV(14, 8),
1605 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL }
1606 	},
1607 	{
1608 		RK3328_CLK_I2C2, RK3328_CRU_CLKSEL_CON(35),
1609 		SEL(7, 7), DIV(6, 0),
1610 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL }
1611 	},
1612 	{
1613 		RK3328_CLK_I2C3, RK3328_CRU_CLKSEL_CON(35),
1614 		SEL(15, 15), DIV(14, 8),
1615 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL }
1616 	},
1617 	{
1618 		RK3328_CLK_CRYPTO, RK3328_CRU_CLKSEL_CON(20),
1619 		SEL(7, 7), DIV(4, 0),
1620 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL }
1621 	},
1622 	{
1623 		RK3328_CLK_PDM, RK3328_CRU_CLKSEL_CON(20),
1624 		SEL(15, 14), DIV(12, 8),
1625 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_PLL_APLL },
1626 		FIXED_PARENT | SET_PARENT
1627 	},
1628 	{
1629 		RK3328_CLK_VDEC_CABAC, RK3328_CRU_CLKSEL_CON(48),
1630 		SEL(15, 14), DIV(12, 8),
1631 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY,
1632 		  RK3328_USB480M }
1633 	},
1634 	{
1635 		RK3328_CLK_VDEC_CORE, RK3328_CRU_CLKSEL_CON(49),
1636 		SEL(7, 6), DIV(4, 0),
1637 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY,
1638 		  RK3328_USB480M }
1639 	},
1640 	{
1641 		RK3328_CLK_VENC_DSP, RK3328_CRU_CLKSEL_CON(52),
1642 		SEL(15, 14), DIV(12, 8),
1643 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY,
1644 		  RK3328_USB480M }
1645 	},
1646 	{
1647 		RK3328_CLK_VENC_CORE, RK3328_CRU_CLKSEL_CON(51),
1648 		SEL(15, 14), DIV(12, 8),
1649 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY,
1650 		  RK3328_USB480M }
1651 	},
1652 	{
1653 		RK3328_CLK_TSP, RK3328_CRU_CLKSEL_CON(21),
1654 		SEL(15, 15), DIV(12, 8),
1655 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL }
1656 	},
1657 	{
1658 		RK3328_CLK_MAC2IO_SRC, RK3328_CRU_CLKSEL_CON(27),
1659 		SEL(7, 7), DIV(4, 0),
1660 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL }
1661 	},
1662 	{
1663 		RK3328_DCLK_LCDC, RK3328_CRU_CLKSEL_CON(40),
1664 		SEL(1, 1), 0,
1665 		{ RK3328_HDMIPHY, RK3328_DCLK_LCDC_SRC }
1666 	},
1667 	{
1668 		RK3328_ACLK_VOP_PRE, RK3328_CRU_CLKSEL_CON(39),
1669 		SEL(7, 6), DIV(4, 0),
1670 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY,
1671 		  RK3328_USB480M }
1672 	},
1673 	{
1674 		RK3328_ACLK_RGA_PRE, RK3328_CRU_CLKSEL_CON(36),
1675 		SEL(15, 14), DIV(12, 8),
1676 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY,
1677 		  RK3328_USB480M }
1678 	},
1679 	{
1680 		RK3328_ACLK_BUS_PRE, RK3328_CRU_CLKSEL_CON(0),
1681 		SEL(14, 13), DIV(12, 8),
1682 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY }
1683 	},
1684 	{
1685 		RK3328_ACLK_PERI_PRE, RK3328_CRU_CLKSEL_CON(28),
1686 		SEL(7, 6), DIV(4, 0),
1687 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY }
1688 	},
1689 	{
1690 		RK3328_ACLK_RKVDEC_PRE, RK3328_CRU_CLKSEL_CON(48),
1691 		SEL(7, 6), DIV(4, 0),
1692 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY,
1693 		  RK3328_USB480M }
1694 	},
1695 	{
1696 		RK3328_ACLK_RKVENC, RK3328_CRU_CLKSEL_CON(51),
1697 		SEL(7, 6), DIV(4, 0),
1698 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY,
1699 		  RK3328_USB480M }
1700 	},
1701 	{
1702 		RK3328_ACLK_VPU_PRE, RK3328_CRU_CLKSEL_CON(50),
1703 		SEL(7, 6), DIV(4, 0),
1704 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY,
1705 		  RK3328_USB480M }
1706 	},
1707 	{
1708 		RK3328_ACLK_VIO_PRE, RK3328_CRU_CLKSEL_CON(37),
1709 		SEL(7, 6), DIV(4, 0),
1710 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY,
1711 		  RK3328_USB480M }
1712 	},
1713 	{
1714 		RK3328_PCLK_BUS_PRE, RK3328_CRU_CLKSEL_CON(1),
1715 		0, DIV(14, 12),
1716 		{ RK3328_ACLK_BUS_PRE }
1717 	},
1718 	{
1719 		RK3328_HCLK_BUS_PRE, RK3328_CRU_CLKSEL_CON(1),
1720 		0, DIV(9, 8),
1721 		{ RK3328_ACLK_BUS_PRE }
1722 	},
1723 	{
1724 		RK3328_PCLK_PERI, RK3328_CRU_CLKSEL_CON(29),
1725 		0, DIV(6, 4),
1726 		{ RK3328_ACLK_PERI_PRE }
1727 	},
1728 	{
1729 		RK3328_HCLK_PERI, RK3328_CRU_CLKSEL_CON(29),
1730 		0, DIV(1, 0),
1731 		{ RK3328_ACLK_PERI_PRE }
1732 	},
1733 	{
1734 		RK3328_CLK_24M, RK3328_CRU_CLKSEL_CON(2),
1735 		0, DIV(12, 8),
1736 		{ RK3328_XIN24M }
1737 	},
1738 	{
1739 		/* Sentinel */
1740 	}
1741 };
1742 
1743 void
rk3328_init(struct rkclock_softc * sc)1744 rk3328_init(struct rkclock_softc *sc)
1745 {
1746 	int i;
1747 
1748 	/* The code below assumes all clocks are enabled.  Check this!. */
1749 	for (i = 0; i <= 28; i++) {
1750 		if (HREAD4(sc, RK3328_CRU_CLKGATE_CON(i)) != 0x00000000) {
1751 			printf("CRU_CLKGATE_CON%d: 0x%08x\n", i,
1752 			    HREAD4(sc, RK3328_CRU_CLKGATE_CON(i)));
1753 		}
1754 	}
1755 
1756 	sc->sc_clocks = rk3328_clocks;
1757 }
1758 
1759 uint32_t
rk3328_armclk_parent(uint32_t mux)1760 rk3328_armclk_parent(uint32_t mux)
1761 {
1762 	switch (mux) {
1763 	case 0:
1764 		return RK3328_PLL_APLL;
1765 	case 1:
1766 		return RK3328_PLL_GPLL;
1767 	case 2:
1768 		return RK3328_PLL_DPLL;
1769 	case 3:
1770 		return RK3328_PLL_NPLL;
1771 	}
1772 
1773 	return 0;
1774 }
1775 
1776 uint32_t
rk3328_get_armclk(struct rkclock_softc * sc)1777 rk3328_get_armclk(struct rkclock_softc *sc)
1778 {
1779 	uint32_t reg, mux, div_con;
1780 	uint32_t idx;
1781 
1782 	reg = HREAD4(sc, RK3328_CRU_CLKSEL_CON(0));
1783 	mux = (reg & RK3328_CRU_CORE_CLK_PLL_SEL_MASK) >>
1784 	    RK3328_CRU_CORE_CLK_PLL_SEL_SHIFT;
1785 	div_con = (reg & RK3328_CRU_CLK_CORE_DIV_CON_MASK) >>
1786 	    RK3328_CRU_CLK_CORE_DIV_CON_SHIFT;
1787 	idx = rk3328_armclk_parent(mux);
1788 
1789 	return rk3328_get_frequency(sc, &idx) / (div_con + 1);
1790 }
1791 
1792 int
rk3328_set_armclk(struct rkclock_softc * sc,uint32_t freq)1793 rk3328_set_armclk(struct rkclock_softc *sc, uint32_t freq)
1794 {
1795 	uint32_t reg, mux;
1796 	uint32_t old_freq, div;
1797 	uint32_t idx;
1798 
1799 	old_freq = rk3328_get_armclk(sc);
1800 	if (freq == old_freq)
1801 		return 0;
1802 
1803 	reg = HREAD4(sc, RK3328_CRU_CLKSEL_CON(0));
1804 	mux = (reg & RK3328_CRU_CORE_CLK_PLL_SEL_MASK) >>
1805 	    RK3328_CRU_CORE_CLK_PLL_SEL_SHIFT;
1806 
1807 	/* Keep the pclk_dbg clock at or below 300 MHz. */
1808 	div = 1;
1809 	while (freq / (div + 1) > 300000000)
1810 		div++;
1811 	/* and make sure we use an odd divider. */
1812 	if ((div % 2) == 0)
1813 		div++;
1814 
1815 	/* When ramping up, set clock dividers first. */
1816 	if (freq > old_freq) {
1817 		HWRITE4(sc, RK3328_CRU_CLKSEL_CON(0),
1818 		    RK3328_CRU_CLK_CORE_DIV_CON_MASK << 16 |
1819 		    0 << RK3328_CRU_CLK_CORE_DIV_CON_SHIFT);
1820 		HWRITE4(sc, RK3328_CRU_CLKSEL_CON(1),
1821 		    RK3328_CRU_ACLK_CORE_DIV_CON_MASK << 16 |
1822 		    1 << RK3328_CRU_ACLK_CORE_DIV_CON_SHIFT |
1823 		    RK3328_CRU_CLK_CORE_DBG_DIV_CON_MASK << 16 |
1824 		    div << RK3328_CRU_CLK_CORE_DBG_DIV_CON_SHIFT);
1825 	}
1826 
1827 	/* We always use NPLL and force the switch below if needed. */
1828 	idx = RK3328_PLL_NPLL;
1829 	rk3328_set_frequency(sc, &idx, freq);
1830 
1831 	/* When ramping down, set clock dividers last. */
1832 	if (freq < old_freq || mux != 3) {
1833 		HWRITE4(sc, RK3328_CRU_CLKSEL_CON(0),
1834 		    RK3328_CRU_CORE_CLK_PLL_SEL_MASK << 16 |
1835 		    3 << RK3328_CRU_CORE_CLK_PLL_SEL_SHIFT |
1836 		    RK3328_CRU_CLK_CORE_DIV_CON_MASK << 16 |
1837 		    0 << RK3328_CRU_CLK_CORE_DIV_CON_SHIFT);
1838 		HWRITE4(sc, RK3328_CRU_CLKSEL_CON(1),
1839 		    RK3328_CRU_ACLK_CORE_DIV_CON_MASK << 16 |
1840 		    1 << RK3328_CRU_ACLK_CORE_DIV_CON_SHIFT |
1841 		    RK3328_CRU_CLK_CORE_DBG_DIV_CON_MASK << 16 |
1842 		    div << RK3328_CRU_CLK_CORE_DBG_DIV_CON_SHIFT);
1843 	}
1844 
1845 	return 0;
1846 }
1847 
1848 uint32_t
rk3328_get_pll(struct rkclock_softc * sc,bus_size_t base)1849 rk3328_get_pll(struct rkclock_softc *sc, bus_size_t base)
1850 {
1851 	uint32_t fbdiv, postdiv1, postdiv2, refdiv;
1852 	uint32_t dsmpd, fracdiv;
1853 	uint64_t frac = 0;
1854 	uint32_t reg;
1855 
1856 	reg = HREAD4(sc, base + 0x0000);
1857 	postdiv1 = (reg & RK3328_CRU_PLL_POSTDIV1_MASK) >>
1858 	    RK3328_CRU_PLL_POSTDIV1_SHIFT;
1859 	fbdiv = (reg & RK3328_CRU_PLL_FBDIV_MASK) >>
1860 	    RK3328_CRU_PLL_FBDIV_SHIFT;
1861 	reg = HREAD4(sc, base + 0x0004);
1862 	dsmpd = (reg & RK3328_CRU_PLL_DSMPD);
1863 	postdiv2 = (reg & RK3328_CRU_PLL_POSTDIV2_MASK) >>
1864 	    RK3328_CRU_PLL_POSTDIV2_SHIFT;
1865 	refdiv = (reg & RK3328_CRU_PLL_REFDIV_MASK) >>
1866 	    RK3328_CRU_PLL_REFDIV_SHIFT;
1867 	reg = HREAD4(sc, base + 0x0008);
1868 	fracdiv = (reg & RK3328_CRU_PLL_FRACDIV_MASK) >>
1869 	    RK3328_CRU_PLL_FRACDIV_SHIFT;
1870 
1871 	if (dsmpd == 0)
1872 		frac = (24000000ULL * fracdiv / refdiv) >> 24;
1873 	return ((24000000ULL * fbdiv / refdiv) + frac) / postdiv1 / postdiv2;
1874 }
1875 
1876 int
rk3328_set_pll(struct rkclock_softc * sc,bus_size_t base,uint32_t freq)1877 rk3328_set_pll(struct rkclock_softc *sc, bus_size_t base, uint32_t freq)
1878 {
1879 	uint32_t fbdiv, postdiv1, postdiv2, refdiv;
1880 	int mode_shift = -1;
1881 
1882 	switch (base) {
1883 	case RK3328_CRU_APLL_CON(0):
1884 		mode_shift = 0;
1885 		break;
1886 	case RK3328_CRU_DPLL_CON(0):
1887 		mode_shift = 4;
1888 		break;
1889 	case RK3328_CRU_CPLL_CON(0):
1890 		mode_shift = 8;
1891 		break;
1892 	case RK3328_CRU_GPLL_CON(0):
1893 		mode_shift = 12;
1894 		break;
1895 	case RK3328_CRU_NPLL_CON(0):
1896 		mode_shift = 1;
1897 		break;
1898 	}
1899 	KASSERT(mode_shift != -1);
1900 
1901 	/*
1902 	 * It is not clear whether all combinations of the clock
1903 	 * dividers result in a stable clock.  Therefore this function
1904 	 * only supports a limited set of PLL clock rates.  For now
1905 	 * this set covers all the CPU frequencies supported by the
1906 	 * Linux kernel.
1907 	 */
1908 	switch (freq) {
1909 	case 1800000000U:
1910 	case 1704000000U:
1911 	case 1608000000U:
1912 	case 1512000000U:
1913 	case 1488000000U:
1914 	case 1416000000U:
1915 	case 1392000000U:
1916 	case 1296000000U:
1917 	case 1200000000U:
1918 	case 1104000000U:
1919 		postdiv1 = postdiv2 = refdiv = 1;
1920 		break;
1921 	case 1008000000U:
1922 	case 912000000U:
1923 	case 816000000U:
1924 	case 696000000U:
1925 		postdiv1 = 2; postdiv2 = refdiv = 1;
1926 		break;
1927 	case 600000000U:
1928 		postdiv1 = 3; postdiv2 = refdiv = 1;
1929 		break;
1930 	case 408000000U:
1931 	case 312000000U:
1932 		postdiv1 = postdiv2 = 2; refdiv = 1;
1933 		break;
1934 	case 216000000U:
1935 		postdiv1 = 4; postdiv2 = 2; refdiv = 1;
1936 		break;
1937 	case 96000000U:
1938 		postdiv1 = postdiv2 = 4; refdiv = 1;
1939 		break;
1940 	default:
1941 		printf("%s: %u Hz\n", __func__, freq);
1942 		return -1;
1943 	}
1944 
1945 	/* Calculate feedback divider. */
1946 	fbdiv = freq * postdiv1 * postdiv2 * refdiv / 24000000;
1947 
1948 	/*
1949 	 * Select slow mode to guarantee a stable clock while we're
1950 	 * adjusting the PLL.
1951 	 */
1952 	HWRITE4(sc, RK3328_CRU_CRU_MODE,
1953 	   (RK3328_CRU_CRU_MODE_MASK << 16 |
1954 	   RK3328_CRU_CRU_MODE_SLOW) << mode_shift);
1955 
1956 	/* Set PLL rate. */
1957 	HWRITE4(sc, base + 0x0000,
1958 	    RK3328_CRU_PLL_POSTDIV1_MASK << 16 |
1959 	    postdiv1 << RK3328_CRU_PLL_POSTDIV1_SHIFT |
1960 	    RK3328_CRU_PLL_FBDIV_MASK << 16 |
1961 	    fbdiv << RK3328_CRU_PLL_FBDIV_SHIFT);
1962 	HWRITE4(sc, base + 0x0004,
1963 	    RK3328_CRU_PLL_DSMPD << 16 | RK3328_CRU_PLL_DSMPD |
1964 	    RK3328_CRU_PLL_POSTDIV2_MASK << 16 |
1965 	    postdiv2 << RK3328_CRU_PLL_POSTDIV2_SHIFT |
1966 	    RK3328_CRU_PLL_REFDIV_MASK << 16 |
1967 	    refdiv << RK3328_CRU_PLL_REFDIV_SHIFT);
1968 
1969 	/* Wait for PLL to stabilize. */
1970 	while ((HREAD4(sc, base + 0x0004) & RK3328_CRU_PLL_PLL_LOCK) == 0)
1971 		delay(10);
1972 
1973 	/* Switch back to normal mode. */
1974 	HWRITE4(sc, RK3328_CRU_CRU_MODE,
1975 	   (RK3328_CRU_CRU_MODE_MASK << 16 |
1976 	   RK3328_CRU_CRU_MODE_NORMAL) << mode_shift);
1977 
1978 	return 0;
1979 }
1980 
1981 int
rk3328_set_frac_pll(struct rkclock_softc * sc,bus_size_t base,uint32_t freq)1982 rk3328_set_frac_pll(struct rkclock_softc *sc, bus_size_t base, uint32_t freq)
1983 {
1984 	uint32_t fbdiv, postdiv1, postdiv2, refdiv, fracdiv;
1985 	int mode_shift = -1;
1986 	uint32_t reg;
1987 
1988 	switch (base) {
1989 	case RK3328_CRU_APLL_CON(0):
1990 		mode_shift = 0;
1991 		break;
1992 	case RK3328_CRU_DPLL_CON(0):
1993 		mode_shift = 4;
1994 		break;
1995 	case RK3328_CRU_CPLL_CON(0):
1996 		mode_shift = 8;
1997 		break;
1998 	case RK3328_CRU_GPLL_CON(0):
1999 		mode_shift = 12;
2000 		break;
2001 	case RK3328_CRU_NPLL_CON(0):
2002 		mode_shift = 1;
2003 		break;
2004 	}
2005 	KASSERT(mode_shift != -1);
2006 
2007 	/*
2008 	 * It is not clear whether all combinations of the clock
2009 	 * dividers result in a stable clock.  Therefore this function
2010 	 * only supports a limited set of PLL clock rates.  This set
2011 	 * set covers all the fractional PLL frequencies supported by
2012 	 * the Linux kernel.
2013 	 */
2014 	switch (freq) {
2015 	case 1016064000U:
2016 		postdiv1 = postdiv2 = 1; refdiv = 3; fracdiv = 134217;
2017 		break;
2018 	case 983040000U:
2019 		postdiv1 = postdiv2 = 1; refdiv = 24; fracdiv = 671088;
2020 		break;
2021 	case 491520000U:
2022 		postdiv1 = 2; postdiv2 = 1; refdiv = 24; fracdiv = 671088;
2023 		break;
2024 	case 61440000U:
2025 		postdiv1 = 7; postdiv2 = 2; refdiv = 6; fracdiv = 671088;
2026 		break;
2027 	case 56448000U:
2028 		postdiv1 = postdiv2 = 4; refdiv = 12; fracdiv = 9797894;
2029 		break;
2030 	case 40960000U:
2031 		postdiv1 = 4; postdiv2 = 5; refdiv = 12; fracdiv = 10066239;
2032 		break;
2033 	default:
2034 		printf("%s: %u Hz\n", __func__, freq);
2035 		return -1;
2036 	}
2037 
2038 	/* Calculate feedback divider. */
2039 	fbdiv = (uint64_t)freq * postdiv1 * postdiv2 * refdiv / 24000000;
2040 
2041 	/*
2042 	 * Select slow mode to guarantee a stable clock while we're
2043 	 * adjusting the PLL.
2044 	 */
2045 	HWRITE4(sc, RK3328_CRU_CRU_MODE,
2046 	   (RK3328_CRU_CRU_MODE_MASK << 16 |
2047 	   RK3328_CRU_CRU_MODE_SLOW) << mode_shift);
2048 
2049 	/* Set PLL rate. */
2050 	HWRITE4(sc, base + 0x0000,
2051 	    RK3328_CRU_PLL_POSTDIV1_MASK << 16 |
2052 	    postdiv1 << RK3328_CRU_PLL_POSTDIV1_SHIFT |
2053 	    RK3328_CRU_PLL_FBDIV_MASK << 16 |
2054 	    fbdiv << RK3328_CRU_PLL_FBDIV_SHIFT);
2055 	HWRITE4(sc, base + 0x0004,
2056 	    RK3328_CRU_PLL_DSMPD << 16 |
2057 	    RK3328_CRU_PLL_POSTDIV2_MASK << 16 |
2058 	    postdiv2 << RK3328_CRU_PLL_POSTDIV2_SHIFT |
2059 	    RK3328_CRU_PLL_REFDIV_MASK << 16 |
2060 	    refdiv << RK3328_CRU_PLL_REFDIV_SHIFT);
2061 	reg = HREAD4(sc, base + 0x0008);
2062 	reg &= ~RK3328_CRU_PLL_FRACDIV_MASK;
2063 	reg |= fracdiv << RK3328_CRU_PLL_FRACDIV_SHIFT;
2064 	HWRITE4(sc, base + 0x0008, reg);
2065 
2066 	/* Wait for PLL to stabilize. */
2067 	while ((HREAD4(sc, base + 0x0004) & RK3328_CRU_PLL_PLL_LOCK) == 0)
2068 		delay(10);
2069 
2070 	/* Switch back to normal mode. */
2071 	HWRITE4(sc, RK3328_CRU_CRU_MODE,
2072 	   (RK3328_CRU_CRU_MODE_MASK << 16 |
2073 	   RK3328_CRU_CRU_MODE_NORMAL) << mode_shift);
2074 
2075 	return 0;
2076 }
2077 
2078 uint32_t
rk3328_get_frequency(void * cookie,uint32_t * cells)2079 rk3328_get_frequency(void *cookie, uint32_t *cells)
2080 {
2081 	struct rkclock_softc *sc = cookie;
2082 	uint32_t idx = cells[0];
2083 	uint32_t reg;
2084 
2085 	switch (idx) {
2086 	case RK3328_PLL_APLL:
2087 		return rk3328_get_pll(sc, RK3328_CRU_APLL_CON(0));
2088 	case RK3328_PLL_DPLL:
2089 		return rk3328_get_pll(sc, RK3328_CRU_DPLL_CON(0));
2090 	case RK3328_PLL_CPLL:
2091 		return rk3328_get_pll(sc, RK3328_CRU_CPLL_CON(0));
2092 	case RK3328_PLL_GPLL:
2093 		return rk3328_get_pll(sc, RK3328_CRU_GPLL_CON(0));
2094 	case RK3328_PLL_NPLL:
2095 		return rk3328_get_pll(sc, RK3328_CRU_NPLL_CON(0));
2096 	case RK3328_ARMCLK:
2097 		return rk3328_get_armclk(sc);
2098 	case RK3328_XIN24M:
2099 		return 24000000;
2100 	case RK3328_GMAC_CLKIN:
2101 		return 125000000;
2102 	/*
2103 	 * XXX The HDMIPHY and USB480M clocks are external.  Returning
2104 	 * zero here will cause them to be ignored for reparenting
2105 	 * purposes.
2106 	 */
2107 	case RK3328_HDMIPHY:
2108 		return 0;
2109 	case RK3328_USB480M:
2110 		return 0;
2111 	case RK3328_CLK_MAC2IO:
2112 		reg = regmap_read_4(sc->sc_grf, RK3328_GRF_MAC_CON1);
2113 		if (reg & RK3328_GRF_GMAC2IO_RMII_EXTCLK_SEL)
2114 			idx = RK3328_GMAC_CLKIN;
2115 		else
2116 			idx = RK3328_CLK_MAC2IO_SRC;
2117 		return rk3328_get_frequency(sc, &idx);
2118 	default:
2119 		break;
2120 	}
2121 
2122 	return rkclock_get_frequency(sc, idx);
2123 }
2124 
2125 int
rk3328_set_frequency(void * cookie,uint32_t * cells,uint32_t freq)2126 rk3328_set_frequency(void *cookie, uint32_t *cells, uint32_t freq)
2127 {
2128 	struct rkclock_softc *sc = cookie;
2129 	uint32_t idx = cells[0];
2130 	uint32_t reg, mux;
2131 
2132 	switch (idx) {
2133 	case RK3328_PLL_APLL:
2134 		return rk3328_set_frac_pll(sc, RK3328_CRU_APLL_CON(0), freq);
2135 	case RK3328_PLL_DPLL:
2136 		return rk3328_set_pll(sc, RK3328_CRU_DPLL_CON(0), freq);
2137 	case RK3328_PLL_CPLL:
2138 		return rk3328_set_pll(sc, RK3328_CRU_CPLL_CON(0), freq);
2139 	case RK3328_PLL_GPLL:
2140 		return rk3328_set_frac_pll(sc, RK3328_CRU_GPLL_CON(0), freq);
2141 	case RK3328_PLL_NPLL:
2142 		return rk3328_set_pll(sc, RK3328_CRU_NPLL_CON(0), freq);
2143 	case RK3328_ARMCLK:
2144 		return rk3328_set_armclk(sc, freq);
2145 	case RK3328_CLK_UART0:
2146 	case RK3328_CLK_UART1:
2147 	case RK3328_CLK_UART2:
2148 		if (freq == rk3328_get_frequency(sc, &idx))
2149 			return 0;
2150 		break;
2151 	case RK3328_DCLK_LCDC:
2152 		reg = HREAD4(sc, RK3328_CRU_CLKSEL_CON(40));
2153 		mux = (reg & RK3328_CRU_VOP_DCLK_SRC_SEL_MASK) >>
2154 		    RK3328_CRU_VOP_DCLK_SRC_SEL_SHIFT;
2155 		idx = (mux == 0) ? RK3328_HDMIPHY : RK3328_DCLK_LCDC_SRC;
2156 		return rk3328_set_frequency(sc, &idx, freq);
2157 	case RK3328_HCLK_CRYPTO_SLV:
2158 		idx = RK3328_HCLK_BUS_PRE;
2159 		return rk3328_set_frequency(sc, &idx, freq);
2160 	default:
2161 		break;
2162 	}
2163 
2164 	return rkclock_set_frequency(sc, idx, freq);
2165 }
2166 
2167 int
rk3328_set_parent(void * cookie,uint32_t * cells,uint32_t * pcells)2168 rk3328_set_parent(void *cookie, uint32_t *cells, uint32_t *pcells)
2169 {
2170 	struct rkclock_softc *sc = cookie;
2171 	uint32_t idx = cells[0];
2172 	uint32_t parent;
2173 
2174 	if (pcells[0] == sc->sc_phandle)
2175 		parent = pcells[1];
2176 	else {
2177 		char name[32];
2178 		int node;
2179 
2180 		node = OF_getnodebyphandle(pcells[0]);
2181 		if (node == 0)
2182 			return -1;
2183 		name[0] = 0;
2184 		OF_getprop(node, "clock-output-names", name, sizeof(name));
2185 		name[sizeof(name) - 1] = 0;
2186 		if (strcmp(name, "xin24m") == 0)
2187 			parent = RK3328_XIN24M;
2188 		else if (strcmp(name, "gmac_clkin") == 0)
2189 			parent = RK3328_GMAC_CLKIN;
2190 		else
2191 			return -1;
2192 	}
2193 
2194 	switch (idx) {
2195 	case RK3328_CLK_MAC2IO:
2196 		if (parent == RK3328_GMAC_CLKIN) {
2197 			regmap_write_4(sc->sc_grf, RK3328_GRF_MAC_CON1,
2198 			    RK3328_GRF_GMAC2IO_RMII_EXTCLK_SEL << 16 |
2199 			    RK3328_GRF_GMAC2IO_RMII_EXTCLK_SEL);
2200 		} else {
2201 			regmap_write_4(sc->sc_grf, RK3328_GRF_MAC_CON1,
2202 			    RK3328_GRF_GMAC2IO_RMII_EXTCLK_SEL << 16);
2203 		}
2204 		return 0;
2205 	case RK3328_CLK_MAC2IO_EXT:
2206 		if (parent == RK3328_GMAC_CLKIN) {
2207 			regmap_write_4(sc->sc_grf, RK3328_GRF_SOC_CON4,
2208 			    RK3328_GRF_GMAC2IO_MAC_CLK_OUTPUT_EN << 16 |
2209 			    RK3328_GRF_GMAC2IO_MAC_CLK_OUTPUT_EN);
2210 		} else {
2211 			regmap_write_4(sc->sc_grf, RK3328_GRF_SOC_CON4,
2212 			    RK3328_GRF_GMAC2IO_MAC_CLK_OUTPUT_EN << 16);
2213 		}
2214 		return 0;
2215 	}
2216 
2217 	return rkclock_set_parent(sc, idx, parent);
2218 }
2219 
2220 void
rk3328_enable(void * cookie,uint32_t * cells,int on)2221 rk3328_enable(void *cookie, uint32_t *cells, int on)
2222 {
2223 	uint32_t idx = cells[0];
2224 
2225 	/*
2226 	 * All clocks are enabled by default, so there is nothing for
2227 	 * us to do until we start disabling clocks.
2228 	 */
2229 	if (!on)
2230 		printf("%s: 0x%08x\n", __func__, idx);
2231 }
2232 
2233 void
rk3328_reset(void * cookie,uint32_t * cells,int on)2234 rk3328_reset(void *cookie, uint32_t *cells, int on)
2235 {
2236 	struct rkclock_softc *sc = cookie;
2237 	uint32_t idx = cells[0];
2238 	uint32_t mask = (1 << (idx % 16));
2239 
2240 	HWRITE4(sc, RK3328_CRU_SOFTRST_CON(idx / 16),
2241 	    mask << 16 | (on ? mask : 0));
2242 }
2243 
2244 /*
2245  * Rockchip RK3399
2246  */
2247 
2248 const struct rkclock rk3399_clocks[] = {
2249 	{
2250 		RK3399_CLK_I2C1, RK3399_CRU_CLKSEL_CON(61),
2251 		SEL(7, 7), DIV(6, 0),
2252 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL }
2253 	},
2254 	{
2255 		RK3399_CLK_I2C2, RK3399_CRU_CLKSEL_CON(62),
2256 		SEL(7, 7), DIV(6, 0),
2257 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL }
2258 	},
2259 	{
2260 		RK3399_CLK_I2C3, RK3399_CRU_CLKSEL_CON(63),
2261 		SEL(7, 7), DIV(6, 0),
2262 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL }
2263 	},
2264 	{
2265 		RK3399_CLK_I2C5, RK3399_CRU_CLKSEL_CON(61),
2266 		SEL(15, 15), DIV(14, 8),
2267 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL }
2268 	},
2269 	{
2270 		RK3399_CLK_I2C6, RK3399_CRU_CLKSEL_CON(62),
2271 		SEL(15, 15), DIV(14, 8),
2272 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL }
2273 	},
2274 	{
2275 		RK3399_CLK_I2C7, RK3399_CRU_CLKSEL_CON(63),
2276 		SEL(15, 15), DIV(14, 8),
2277 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL }
2278 	},
2279 	{
2280 		RK3399_CLK_SPI0, RK3399_CRU_CLKSEL_CON(59),
2281 		SEL(7, 7), DIV(6, 0),
2282 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL }
2283 	},
2284 	{
2285 		RK3399_CLK_SPI1, RK3399_CRU_CLKSEL_CON(59),
2286 		SEL(15, 15), DIV(14, 8),
2287 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL }
2288 	},
2289 	{
2290 		RK3399_CLK_SPI2, RK3399_CRU_CLKSEL_CON(60),
2291 		SEL(7, 7), DIV(6, 0),
2292 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL }
2293 	},
2294 	{
2295 		RK3399_CLK_SPI4, RK3399_CRU_CLKSEL_CON(60),
2296 		SEL(15, 15), DIV(14, 8),
2297 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL }
2298 	},
2299 	{
2300 		RK3399_CLK_SPI5, RK3399_CRU_CLKSEL_CON(58),
2301 		SEL(15, 15), DIV(14, 8),
2302 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL }
2303 	},
2304 	{
2305 		RK3399_CLK_SDMMC, RK3399_CRU_CLKSEL_CON(16),
2306 		SEL(10, 8), DIV(6, 0),
2307 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL, RK3399_PLL_NPLL,
2308 		  /* RK3399_PLL_PPLL */ 0, /* RK3399_USB_480M */ 0,
2309 		  RK3399_XIN24M }
2310 	},
2311 	{
2312 		RK3399_CLK_SDIO, RK3399_CRU_CLKSEL_CON(15),
2313 		SEL(10, 8), DIV(6, 0),
2314 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL, RK3399_PLL_NPLL,
2315 		  /* RK3399_PLL_PPLL */ 0, /* RK3399_USB_480M */ 0,
2316 		  RK3399_XIN24M }
2317 	},
2318 	{
2319 		RK3399_CLK_EMMC, RK3399_CRU_CLKSEL_CON(22),
2320 		SEL(10, 8), DIV(6, 0),
2321 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL, RK3399_PLL_NPLL,
2322 		  /* RK3399_USB_480M */ 0, RK3399_XIN24M }
2323 	},
2324 	{
2325 		RK3399_CLK_TSADC, RK3399_CRU_CLKSEL_CON(27),
2326 		SEL(15, 15), DIV(9, 0),
2327 		{ RK3399_XIN24M, RK3399_CLK_32K }
2328 	},
2329 	{
2330 		RK3399_CLK_UART0, RK3399_CRU_CLKSEL_CON(33),
2331 		SEL(9, 8), 0,
2332 		{ 0, 0, RK3399_XIN24M }
2333 	},
2334 	{
2335 		RK3399_CLK_UART1, RK3399_CRU_CLKSEL_CON(34),
2336 		SEL(9, 8), 0,
2337 		{ 0, 0, RK3399_XIN24M }
2338 	},
2339 	{
2340 		RK3399_CLK_UART2, RK3399_CRU_CLKSEL_CON(35),
2341 		SEL(9, 8), 0,
2342 		{ 0, 0, RK3399_XIN24M }
2343 	},
2344 	{
2345 		RK3399_CLK_UART3, RK3399_CRU_CLKSEL_CON(36),
2346 		SEL(9, 8), 0,
2347 		{ 0, 0, RK3399_XIN24M }
2348 	},
2349 	{
2350 		RK3399_CLK_I2S0_8CH, RK3399_CRU_CLKSEL_CON(28),
2351 		SEL(9, 8), 0,
2352 		{ RK3399_CLK_I2S0_DIV, RK3399_CLK_I2S0_FRAC, 0, RK3399_XIN12M },
2353 		SET_PARENT
2354 	},
2355 	{
2356 		RK3399_CLK_I2S1_8CH, RK3399_CRU_CLKSEL_CON(29),
2357 		SEL(9, 8), 0,
2358 		{ RK3399_CLK_I2S1_DIV, RK3399_CLK_I2S1_FRAC, 0, RK3399_XIN12M },
2359 		SET_PARENT
2360 	},
2361 	{
2362 		RK3399_CLK_I2S2_8CH, RK3399_CRU_CLKSEL_CON(30),
2363 		SEL(9, 8), 0,
2364 		{ RK3399_CLK_I2S2_DIV, RK3399_CLK_I2S2_FRAC, 0, RK3399_XIN12M },
2365 		SET_PARENT
2366 	},
2367 	{
2368 		RK3399_CLK_I2S_8CH_OUT, RK3399_CRU_CLKSEL_CON(31),
2369 		SEL(2, 2), 0,
2370 		{ RK3399_CLK_I2SOUT_SRC, RK3399_XIN12M },
2371 		SET_PARENT
2372 	},
2373 	{
2374 		RK3399_CLK_MAC, RK3399_CRU_CLKSEL_CON(20),
2375 		SEL(15, 14), DIV(12, 8),
2376 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL, RK3399_PLL_NPLL }
2377 	},
2378 	{
2379 		RK3399_CLK_UPHY0_TCPDCORE, RK3399_CRU_CLKSEL_CON(64),
2380 		SEL(7, 6), DIV(4, 0),
2381 		{ RK3399_XIN24M, RK3399_CLK_32K, RK3399_PLL_CPLL,
2382 		  RK3399_PLL_GPLL }
2383 	},
2384 	{
2385 		RK3399_CLK_UPHY1_TCPDCORE, RK3399_CRU_CLKSEL_CON(65),
2386 		SEL(7, 6), DIV(4, 0),
2387 		{ RK3399_XIN24M, RK3399_CLK_32K, RK3399_PLL_CPLL,
2388 		  RK3399_PLL_GPLL }
2389 	},
2390 	{
2391 		RK3399_CLK_PCIEPHY_REF, RK3399_CRU_CLKSEL_CON(18),
2392 		SEL(10, 10), 0,
2393 		{ RK3399_XIN24M, RK3399_CLK_PCIEPHY_REF100M },
2394 		SET_PARENT
2395 	},
2396 	{
2397 		RK3399_CLK_PCIEPHY_REF100M, RK3399_CRU_CLKSEL_CON(18),
2398 		0, DIV(15, 11),
2399 		{ RK3399_PLL_NPLL }
2400 	},
2401 	{
2402 		RK3399_DCLK_VOP0, RK3399_CRU_CLKSEL_CON(49),
2403 		SEL(11, 11), 0,
2404 		{ RK3399_DCLK_VOP0_DIV, RK3399_DCLK_VOP0_FRAC },
2405 		SET_PARENT
2406 	},
2407 	{
2408 		RK3399_DCLK_VOP1, RK3399_CRU_CLKSEL_CON(50),
2409 		SEL(11, 11), 0,
2410 		{ RK3399_DCLK_VOP1_DIV, RK3399_DCLK_VOP1_FRAC },
2411 		SET_PARENT
2412 	},
2413 	{
2414 		RK3399_DCLK_VOP0_DIV, RK3399_CRU_CLKSEL_CON(49),
2415 		SEL(9, 8), DIV(7, 0),
2416 		{ RK3399_PLL_VPLL, RK3399_PLL_CPLL, RK3399_PLL_GPLL }
2417 	},
2418 	{
2419 		RK3399_DCLK_VOP1_DIV, RK3399_CRU_CLKSEL_CON(50),
2420 		SEL(9, 8), DIV(7, 0),
2421 		{ RK3399_PLL_VPLL, RK3399_PLL_CPLL, RK3399_PLL_GPLL }
2422 	},
2423 	{
2424 		RK3399_ACLK_PERIPH, RK3399_CRU_CLKSEL_CON(14),
2425 		SEL(7, 7), DIV(4, 0),
2426 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL }
2427 	},
2428 	{
2429 		RK3399_ACLK_PERILP0, RK3399_CRU_CLKSEL_CON(23),
2430 		SEL(7, 7), DIV(4, 0),
2431 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL }
2432 	},
2433 	{
2434 		RK3399_ACLK_VIO, RK3399_CRU_CLKSEL_CON(42),
2435 		SEL(7, 6), DIV(4, 0),
2436 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL, /* RK3399_PLL_PPLL */ }
2437 	},
2438 	{
2439 		RK3399_ACLK_CCI, RK3399_CRU_CLKSEL_CON(5),
2440 		SEL(7, 6), DIV(4, 0),
2441 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL, RK3399_PLL_NPLL,
2442 		  RK3399_PLL_VPLL }
2443 	},
2444 	{
2445 		RK3399_ACLK_VOP0, RK3399_CRU_CLKSEL_CON(47),
2446 		SEL(7, 6), DIV(4, 0),
2447 		{ RK3399_PLL_VPLL, RK3399_PLL_CPLL, RK3399_PLL_GPLL,
2448 		  RK3399_PLL_NPLL }
2449 	},
2450 	{
2451 		RK3399_ACLK_VOP1, RK3399_CRU_CLKSEL_CON(48),
2452 		SEL(7, 6), DIV(4, 0),
2453 		{ RK3399_PLL_VPLL, RK3399_PLL_CPLL, RK3399_PLL_GPLL,
2454 		  RK3399_PLL_NPLL }
2455 	},
2456 	{
2457 		RK3399_ACLK_HDCP, RK3399_CRU_CLKSEL_CON(42),
2458 		SEL(15, 14), DIV(12, 8),
2459 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL, /* RK3399_PLL_PPLL */ }
2460 	},
2461 	{
2462 		RK3399_ACLK_GIC_PRE, RK3399_CRU_CLKSEL_CON(56),
2463 		SEL(15, 15), DIV(12, 8),
2464 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL }
2465 	},
2466 	{
2467 		RK3399_PCLK_PERIPH, RK3399_CRU_CLKSEL_CON(14),
2468 		0, DIV(14, 12),
2469 		{ RK3399_ACLK_PERIPH }
2470 	},
2471 	{
2472 		RK3399_PCLK_PERILP0, RK3399_CRU_CLKSEL_CON(23),
2473 		0, DIV(14, 12),
2474 		{ RK3399_ACLK_PERILP0 }
2475 	},
2476 	{
2477 		RK3399_PCLK_PERILP1, RK3399_CRU_CLKSEL_CON(25),
2478 		0, DIV(10, 8),
2479 		{ RK3399_HCLK_PERILP1 }
2480 	},
2481 	{
2482 		RK3399_PCLK_DDR, RK3399_CRU_CLKSEL_CON(6),
2483 		SEL(15, 15), DIV(12, 8),
2484 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL }
2485 	},
2486 	{
2487 		RK3399_PCLK_WDT, RK3399_CRU_CLKSEL_CON(57),
2488 		0, DIV(4, 0),
2489 		{ RK3399_PLL_GPLL }
2490 	},
2491 	{
2492 		RK3399_HCLK_PERIPH, RK3399_CRU_CLKSEL_CON(14),
2493 		0, DIV(9, 8),
2494 		{ RK3399_ACLK_PERIPH }
2495 	},
2496 	{
2497 		RK3399_HCLK_PERILP0, RK3399_CRU_CLKSEL_CON(23),
2498 		0, DIV(9, 8),
2499 		{ RK3399_ACLK_PERILP0 }
2500 	},
2501 	{
2502 		RK3399_HCLK_PERILP1, RK3399_CRU_CLKSEL_CON(25),
2503 		SEL(7, 7), DIV(4, 0),
2504 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL }
2505 	},
2506 	{
2507 		RK3399_HCLK_SDMMC, RK3399_CRU_CLKSEL_CON(13),
2508 		SEL(15, 15), DIV(12, 8),
2509 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL }
2510 	},
2511 	{
2512 		RK3399_HCLK_VOP0, RK3399_CRU_CLKSEL_CON(47),
2513 		0, DIV(12, 8),
2514 		{ RK3399_ACLK_VOP0 }
2515 	},
2516 	{
2517 		RK3399_HCLK_VOP1, RK3399_CRU_CLKSEL_CON(48),
2518 		0, DIV(12, 8),
2519 		{ RK3399_ACLK_VOP1 }
2520 	},
2521 	{
2522 		RK3399_CLK_I2S0_DIV, RK3399_CRU_CLKSEL_CON(28),
2523 		SEL(7, 7), DIV(6, 0),
2524 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL }
2525 	},
2526 	{
2527 		RK3399_CLK_I2S1_DIV, RK3399_CRU_CLKSEL_CON(29),
2528 		SEL(7, 7), DIV(6, 0),
2529 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL }
2530 	},
2531 	{
2532 		RK3399_CLK_I2S2_DIV, RK3399_CRU_CLKSEL_CON(30),
2533 		SEL(7, 7), DIV(6, 0),
2534 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL }
2535 	},
2536 	{
2537 		RK3399_CLK_I2SOUT_SRC, RK3399_CRU_CLKSEL_CON(31),
2538 		SEL(1, 0), 0,
2539 		{ RK3399_CLK_I2S0_8CH, RK3399_CLK_I2S1_8CH,
2540 		  RK3399_CLK_I2S2_8CH },
2541 		SET_PARENT
2542 	},
2543 	{
2544 		/* Sentinel */
2545 	}
2546 };
2547 
2548 /* Some of our parent clocks live in the PMUCRU. */
2549 struct rkclock_softc *rk3399_pmucru_sc;
2550 
2551 void
rk3399_init(struct rkclock_softc * sc)2552 rk3399_init(struct rkclock_softc *sc)
2553 {
2554 	int i;
2555 
2556 	/* PMUCRU instance should attach before us. */
2557 	KASSERT(rk3399_pmucru_sc != NULL);
2558 
2559 	/*
2560 	 * The U-Boot shipped on the Theobroma Systems RK3399-Q7
2561 	 * module is buggy and sets the parent of the clock for the
2562 	 * "big" cluster to LPLL.  Undo that mistake here such that
2563 	 * the clocks of both clusters are independent.
2564 	 */
2565 	HWRITE4(sc, RK3399_CRU_CLKSEL_CON(2),
2566 	    RK3399_CRU_CORE_PLL_SEL_MASK << 16 |
2567 	    RK3399_CRU_CORE_PLL_SEL_BPLL);
2568 
2569 	/* The code below assumes all clocks are enabled.  Check this!. */
2570 	for (i = 0; i <= 34; i++) {
2571 		if (HREAD4(sc, RK3399_CRU_CLKGATE_CON(i)) != 0x00000000) {
2572 			printf("CRU_CLKGATE_CON%d: 0x%08x\n", i,
2573 			    HREAD4(sc, RK3399_CRU_CLKGATE_CON(i)));
2574 		}
2575 	}
2576 
2577 	sc->sc_clocks = rk3399_clocks;
2578 }
2579 
2580 uint32_t
rk3399_get_pll(struct rkclock_softc * sc,bus_size_t base)2581 rk3399_get_pll(struct rkclock_softc *sc, bus_size_t base)
2582 {
2583 	uint32_t fbdiv, postdiv1, postdiv2, refdiv;
2584 	uint32_t pll_work_mode;
2585 	uint32_t reg;
2586 
2587 	reg = HREAD4(sc, base + 0x000c);
2588 	pll_work_mode = reg & RK3399_CRU_PLL_PLL_WORK_MODE_MASK;
2589 	if (pll_work_mode == RK3399_CRU_PLL_PLL_WORK_MODE_SLOW)
2590 		return 24000000;
2591 	if (pll_work_mode == RK3399_CRU_PLL_PLL_WORK_MODE_DEEP_SLOW)
2592 		return 32768;
2593 
2594 	reg = HREAD4(sc, base + 0x0000);
2595 	fbdiv = (reg & RK3399_CRU_PLL_FBDIV_MASK) >>
2596 	    RK3399_CRU_PLL_FBDIV_SHIFT;
2597 	reg = HREAD4(sc, base + 0x0004);
2598 	postdiv2 = (reg & RK3399_CRU_PLL_POSTDIV2_MASK) >>
2599 	    RK3399_CRU_PLL_POSTDIV2_SHIFT;
2600 	postdiv1 = (reg & RK3399_CRU_PLL_POSTDIV1_MASK) >>
2601 	    RK3399_CRU_PLL_POSTDIV1_SHIFT;
2602 	refdiv = (reg & RK3399_CRU_PLL_REFDIV_MASK) >>
2603 	    RK3399_CRU_PLL_REFDIV_SHIFT;
2604 	return 24000000ULL * fbdiv / refdiv / postdiv1 / postdiv2;
2605 }
2606 
2607 int
rk3399_set_pll(struct rkclock_softc * sc,bus_size_t base,uint32_t freq)2608 rk3399_set_pll(struct rkclock_softc *sc, bus_size_t base, uint32_t freq)
2609 {
2610 	uint32_t fbdiv, postdiv1, postdiv2, refdiv;
2611 
2612 	/*
2613 	 * It is not clear whether all combinations of the clock
2614 	 * dividers result in a stable clock.  Therefore this function
2615 	 * only supports a limited set of PLL clock rates.  For now
2616 	 * this set covers all the CPU frequencies supported by the
2617 	 * Linux kernel.
2618 	 */
2619 	switch (freq) {
2620 	case 2208000000U:
2621 	case 2184000000U:
2622 	case 2088000000U:
2623 	case 2040000000U:
2624 	case 2016000000U:
2625 	case 1992000000U:
2626 	case 1896000000U:
2627 	case 1800000000U:
2628 	case 1704000000U:
2629 	case 1608000000U:
2630 	case 1512000000U:
2631 	case 1488000000U:
2632 	case 1416000000U:
2633 	case 1200000000U:
2634 		postdiv1 = postdiv2 = refdiv = 1;
2635 		break;
2636 	case 1008000000U:
2637 	case 816000000U:
2638 	case 696000000U:
2639 		postdiv1 = 2; postdiv2 = refdiv = 1;
2640 		break;
2641 	case 676000000U:
2642 		postdiv1 = 2; postdiv2 = 1; refdiv = 3;
2643 		break;
2644 	case 1000000000U:
2645 	case 800000000U:
2646 	case 600000000U:
2647 		postdiv1 = 3; postdiv2 = refdiv = 1;
2648 		break;
2649 	case 594000000U:
2650 		postdiv1 = 4; postdiv2 = refdiv = 1;
2651 		break;
2652 	case 408000000U:
2653 		postdiv1 = postdiv2 = 2; refdiv = 1;
2654 		break;
2655 	case 297000000U:
2656 	case 216000000U:
2657 		postdiv1 = 4; postdiv2 = 2; refdiv = 1;
2658 		break;
2659 	case 148500000U:
2660 	case 96000000U:
2661 		postdiv1 = postdiv2 = 4; refdiv = 1;
2662 		break;
2663 	case 74250000U:
2664 		postdiv1 = postdiv2 = 4; refdiv = 2;
2665 		break;
2666 	case 65000000U:
2667 	case 54000000U:
2668 	case 27000000U:
2669 		postdiv1 = 6; postdiv2 = 4; refdiv = 1;
2670 		break;
2671 	default:
2672 		printf("%s: %d Hz\n", __func__, freq);
2673 		return -1;
2674 	}
2675 
2676 	/* Calculate feedback divider. */
2677 	fbdiv = freq * postdiv1 * postdiv2 * refdiv / 24000000;
2678 
2679 	/*
2680 	 * Select slow mode to guarantee a stable clock while we're
2681 	 * adjusting the PLL.
2682 	 */
2683 	HWRITE4(sc, base + 0x000c,
2684 	    RK3399_CRU_PLL_PLL_WORK_MODE_MASK << 16 |
2685 	    RK3399_CRU_PLL_PLL_WORK_MODE_SLOW);
2686 
2687 	/* Set PLL rate. */
2688 	HWRITE4(sc, base + 0x0000,
2689 	    RK3399_CRU_PLL_FBDIV_MASK << 16 |
2690 	    fbdiv << RK3399_CRU_PLL_FBDIV_SHIFT);
2691 	HWRITE4(sc, base + 0x0004,
2692 	    RK3399_CRU_PLL_POSTDIV2_MASK << 16 |
2693 	    postdiv2 << RK3399_CRU_PLL_POSTDIV2_SHIFT |
2694 	    RK3399_CRU_PLL_POSTDIV1_MASK << 16 |
2695 	    postdiv1 << RK3399_CRU_PLL_POSTDIV1_SHIFT |
2696 	    RK3399_CRU_PLL_REFDIV_MASK << 16 |
2697 	    refdiv << RK3399_CRU_PLL_REFDIV_SHIFT);
2698 
2699 	/* Wait for PLL to stabilize. */
2700 	while ((HREAD4(sc, base + 0x0008) & RK3399_CRU_PLL_PLL_LOCK) == 0)
2701 		delay(10);
2702 
2703 	/* Switch back to normal mode. */
2704 	HWRITE4(sc, base + 0x000c,
2705 	    RK3399_CRU_PLL_PLL_WORK_MODE_MASK << 16 |
2706 	    RK3399_CRU_PLL_PLL_WORK_MODE_NORMAL);
2707 
2708 	return 0;
2709 }
2710 
2711 uint32_t
rk3399_armclk_parent(uint32_t mux)2712 rk3399_armclk_parent(uint32_t mux)
2713 {
2714 	switch (mux) {
2715 	case 0:
2716 		return RK3399_PLL_ALPLL;
2717 	case 1:
2718 		return RK3399_PLL_ABPLL;
2719 	case 2:
2720 		return RK3399_PLL_DPLL;
2721 	case 3:
2722 		return RK3399_PLL_GPLL;
2723 	}
2724 
2725 	return 0;
2726 }
2727 
2728 uint32_t
rk3399_get_armclk(struct rkclock_softc * sc,bus_size_t clksel)2729 rk3399_get_armclk(struct rkclock_softc *sc, bus_size_t clksel)
2730 {
2731 	uint32_t reg, mux, div_con;
2732 	uint32_t idx;
2733 
2734 	reg = HREAD4(sc, clksel);
2735 	mux = (reg & RK3399_CRU_CORE_PLL_SEL_MASK) >>
2736 	    RK3399_CRU_CORE_PLL_SEL_SHIFT;
2737 	div_con = (reg & RK3399_CRU_CLK_CORE_DIV_CON_MASK) >>
2738 	    RK3399_CRU_CLK_CORE_DIV_CON_SHIFT;
2739 	idx = rk3399_armclk_parent(mux);
2740 
2741 	return rk3399_get_frequency(sc, &idx) / (div_con + 1);
2742 }
2743 
2744 int
rk3399_set_armclk(struct rkclock_softc * sc,bus_size_t clksel,uint32_t freq)2745 rk3399_set_armclk(struct rkclock_softc *sc, bus_size_t clksel, uint32_t freq)
2746 {
2747 	uint32_t reg, mux;
2748 	uint32_t old_freq, div;
2749 	uint32_t idx;
2750 
2751 	old_freq = rk3399_get_armclk(sc, clksel);
2752 	if (freq == old_freq)
2753 		return 0;
2754 
2755 	reg = HREAD4(sc, clksel);
2756 	mux = (reg & RK3399_CRU_CORE_PLL_SEL_MASK) >>
2757 	    RK3399_CRU_CORE_PLL_SEL_SHIFT;
2758 	idx = rk3399_armclk_parent(mux);
2759 
2760 	/* Keep the atclk_core and pclk_dbg clocks at or below 200 MHz. */
2761 	div = 1;
2762 	while (freq / (div + 1) > 200000000)
2763 		div++;
2764 
2765 	/* When ramping up, set clock dividers first. */
2766 	if (freq > old_freq) {
2767 		HWRITE4(sc, clksel,
2768 		    RK3399_CRU_CLK_CORE_DIV_CON_MASK << 16 |
2769 		    0 << RK3399_CRU_CLK_CORE_DIV_CON_SHIFT |
2770 		    RK3399_CRU_ACLKM_CORE_DIV_CON_MASK << 16 |
2771 		    1 << RK3399_CRU_ACLKM_CORE_DIV_CON_SHIFT);
2772 		HWRITE4(sc, clksel + 0x0004,
2773 		    RK3399_CRU_PCLK_DBG_DIV_CON_MASK << 16 |
2774 		    div << RK3399_CRU_PCLK_DBG_DIV_CON_SHIFT |
2775 		    RK3399_CRU_ATCLK_CORE_DIV_CON_MASK << 16 |
2776 		    div << RK3399_CRU_ATCLK_CORE_DIV_CON_SHIFT);
2777 	}
2778 
2779 	rk3399_set_frequency(sc, &idx, freq);
2780 
2781 	/* When ramping down, set clock dividers last. */
2782 	if (freq < old_freq) {
2783 		HWRITE4(sc, clksel,
2784 		    RK3399_CRU_CLK_CORE_DIV_CON_MASK << 16 |
2785 		    0 << RK3399_CRU_CLK_CORE_DIV_CON_SHIFT |
2786 		    RK3399_CRU_ACLKM_CORE_DIV_CON_MASK << 16 |
2787 		    1 << RK3399_CRU_ACLKM_CORE_DIV_CON_SHIFT);
2788 		HWRITE4(sc, clksel + 0x0004,
2789 		    RK3399_CRU_PCLK_DBG_DIV_CON_MASK << 16 |
2790 		    div << RK3399_CRU_PCLK_DBG_DIV_CON_SHIFT |
2791 		    RK3399_CRU_ATCLK_CORE_DIV_CON_MASK << 16 |
2792 		    div << RK3399_CRU_ATCLK_CORE_DIV_CON_SHIFT);
2793 	}
2794 
2795 	return 0;
2796 }
2797 
2798 uint32_t
rk3399_get_frac(struct rkclock_softc * sc,uint32_t parent,bus_size_t base)2799 rk3399_get_frac(struct rkclock_softc *sc, uint32_t parent, bus_size_t base)
2800 {
2801 	uint32_t parent_freq, frac;
2802 	uint16_t n, d;
2803 
2804 	frac = HREAD4(sc, base);
2805 	n = frac >> 16;
2806 	d = frac & 0xffff;
2807 	if (n == 0 || d == 0)
2808 		n = d = 1;
2809 	parent_freq = sc->sc_cd.cd_get_frequency(sc, &parent);
2810 	return ((uint64_t)parent_freq * n) / d;
2811 }
2812 
2813 int
rk3399_set_frac(struct rkclock_softc * sc,uint32_t parent,bus_size_t base,uint32_t freq)2814 rk3399_set_frac(struct rkclock_softc *sc, uint32_t parent, bus_size_t base,
2815     uint32_t freq)
2816 {
2817 	uint32_t n, d;
2818 	uint32_t p0, p1, p2;
2819 	uint32_t q0, q1, q2;
2820 	uint32_t a, tmp;
2821 
2822 	n = freq;
2823 	d = sc->sc_cd.cd_get_frequency(sc, &parent);
2824 
2825 	/*
2826 	 * The denominator needs to be at least 20 times the numerator
2827 	 * for a stable clock.
2828 	 */
2829 	if (n == 0 || d == 0 || d < 20 * n)
2830 		return -1;
2831 
2832 	/*
2833 	 * This is a simplified implementation of the algorithm to
2834 	 * calculate the best rational approximation using continued
2835 	 * fractions.
2836 	 */
2837 
2838 	p0 = q1 = 0;
2839 	p1 = q0 = 1;
2840 
2841 	while (d != 0) {
2842 		/*
2843 		 * Calculate next coefficient in the continued
2844 		 * fraction and keep track of the remainder.
2845 		 */
2846 		tmp = d;
2847 		a = n / d;
2848 		d = n % d;
2849 		n = tmp;
2850 
2851 		/*
2852 		 * Calculate next approximation in the series based on
2853 		 * the current coefficient.
2854 		 */
2855 		p2 = p0 + a * p1;
2856 		q2 = q0 + a * q1;
2857 
2858 		/*
2859 		 * Terminate if we reached the maximum allowed
2860 		 * denominator.
2861 		 */
2862 		if (q2 > 0xffff)
2863 			break;
2864 
2865 		p0 = p1; p1 = p2;
2866 		q0 = q1; q1 = q2;
2867 	}
2868 
2869 	HWRITE4(sc, base, p1 << 16 | q1);
2870 	return 0;
2871 }
2872 
2873 uint32_t
rk3399_get_frequency(void * cookie,uint32_t * cells)2874 rk3399_get_frequency(void *cookie, uint32_t *cells)
2875 {
2876 	struct rkclock_softc *sc = cookie;
2877 	uint32_t idx = cells[0];
2878 
2879 	switch (idx) {
2880 	case RK3399_PLL_ALPLL:
2881 		return rk3399_get_pll(sc, RK3399_CRU_LPLL_CON(0));
2882 	case RK3399_PLL_ABPLL:
2883 		return rk3399_get_pll(sc, RK3399_CRU_BPLL_CON(0));
2884 	case RK3399_PLL_DPLL:
2885 		return rk3399_get_pll(sc, RK3399_CRU_DPLL_CON(0));
2886 	case RK3399_PLL_CPLL:
2887 		return rk3399_get_pll(sc, RK3399_CRU_CPLL_CON(0));
2888 	case RK3399_PLL_GPLL:
2889 		return rk3399_get_pll(sc, RK3399_CRU_GPLL_CON(0));
2890 	case RK3399_PLL_NPLL:
2891 		return rk3399_get_pll(sc, RK3399_CRU_NPLL_CON(0));
2892 	case RK3399_PLL_VPLL:
2893 		return rk3399_get_pll(sc, RK3399_CRU_VPLL_CON(0));
2894 	case RK3399_ARMCLKL:
2895 		return rk3399_get_armclk(sc, RK3399_CRU_CLKSEL_CON(0));
2896 	case RK3399_ARMCLKB:
2897 		return rk3399_get_armclk(sc, RK3399_CRU_CLKSEL_CON(2));
2898 	case RK3399_XIN24M:
2899 		return 24000000;
2900 	case RK3399_CLK_32K:
2901 		return 32768;
2902 	case RK3399_XIN12M:
2903 		return 12000000;
2904 	case RK3399_CLK_I2S0_FRAC:
2905 		return rk3399_get_frac(sc, RK3399_CLK_I2S0_DIV,
2906 		    RK3399_CRU_CLKSEL_CON(96));
2907 	case RK3399_CLK_I2S1_FRAC:
2908 		return rk3399_get_frac(sc, RK3399_CLK_I2S1_DIV,
2909 		    RK3399_CRU_CLKSEL_CON(97));
2910 	case RK3399_CLK_I2S2_FRAC:
2911 		return rk3399_get_frac(sc, RK3399_CLK_I2S2_DIV,
2912 		    RK3399_CRU_CLKSEL_CON(98));
2913 	default:
2914 		break;
2915 	}
2916 
2917 	return rkclock_get_frequency(sc, idx);
2918 }
2919 
2920 int
rk3399_set_frequency(void * cookie,uint32_t * cells,uint32_t freq)2921 rk3399_set_frequency(void *cookie, uint32_t *cells, uint32_t freq)
2922 {
2923 	struct rkclock_softc *sc = cookie;
2924 	uint32_t idx = cells[0];
2925 
2926 	switch (idx) {
2927 	case RK3399_PLL_ALPLL:
2928 		return rk3399_set_pll(sc, RK3399_CRU_LPLL_CON(0), freq);
2929 	case RK3399_PLL_ABPLL:
2930 		return rk3399_set_pll(sc, RK3399_CRU_BPLL_CON(0), freq);
2931 	case RK3399_PLL_CPLL:
2932 		return rk3399_set_pll(sc, RK3399_CRU_CPLL_CON(0), freq);
2933 	case RK3399_PLL_GPLL:
2934 		return rk3399_set_pll(sc, RK3399_CRU_GPLL_CON(0), freq);
2935 	case RK3399_PLL_NPLL:
2936 		return rk3399_set_pll(sc, RK3399_CRU_NPLL_CON(0), freq);
2937 	case RK3399_PLL_VPLL:
2938 		return rk3399_set_pll(sc, RK3399_CRU_VPLL_CON(0), freq);
2939 	case RK3399_ARMCLKL:
2940 		return rk3399_set_armclk(sc, RK3399_CRU_CLKSEL_CON(0), freq);
2941 	case RK3399_ARMCLKB:
2942 		return rk3399_set_armclk(sc, RK3399_CRU_CLKSEL_CON(2), freq);
2943 	case RK3399_CLK_I2S0_8CH:
2944 		rkclock_set_parent(sc, idx, RK3399_CLK_I2S0_FRAC);
2945 		return rkclock_set_frequency(sc, idx, freq);
2946 	case RK3399_CLK_I2S1_8CH:
2947 		rkclock_set_parent(sc, idx, RK3399_CLK_I2S1_FRAC);
2948 		return rkclock_set_frequency(sc, idx, freq);
2949 	case RK3399_CLK_I2S2_8CH:
2950 		rkclock_set_parent(sc, idx, RK3399_CLK_I2S2_FRAC);
2951 		return rkclock_set_frequency(sc, idx, freq);
2952 	case RK3399_XIN12M:
2953 		if (freq / (1000 * 1000) != 12)
2954 			return -1;
2955 		return 0;
2956 	case RK3399_CLK_I2S0_FRAC:
2957 		return rk3399_set_frac(sc, RK3399_CLK_I2S0_DIV,
2958 		    RK3399_CRU_CLKSEL_CON(96), freq);
2959 	case RK3399_CLK_I2S1_FRAC:
2960 		return rk3399_set_frac(sc, RK3399_CLK_I2S1_DIV,
2961 		    RK3399_CRU_CLKSEL_CON(97), freq);
2962 	case RK3399_CLK_I2S2_FRAC:
2963 		return rk3399_set_frac(sc, RK3399_CLK_I2S2_DIV,
2964 		    RK3399_CRU_CLKSEL_CON(98), freq);
2965 	default:
2966 		break;
2967 	}
2968 
2969 	return rkclock_set_frequency(sc, idx, freq);
2970 }
2971 
2972 
2973 int
rk3399_set_parent(void * cookie,uint32_t * cells,uint32_t * pcells)2974 rk3399_set_parent(void *cookie, uint32_t *cells, uint32_t *pcells)
2975 {
2976 	struct rkclock_softc *sc = cookie;
2977 
2978 	if (pcells[0] != sc->sc_phandle)
2979 		return -1;
2980 
2981 	return rkclock_set_parent(sc, cells[0], pcells[1]);
2982 }
2983 
2984 void
rk3399_enable(void * cookie,uint32_t * cells,int on)2985 rk3399_enable(void *cookie, uint32_t *cells, int on)
2986 {
2987 	struct rkclock_softc *sc = cookie;
2988 	uint32_t idx = cells[0];
2989 
2990 	/*
2991 	 * All clocks are enabled upon hardware reset, but on some boards the
2992 	 * firmware will disable some of them.  Handle those here.
2993 	 */
2994 	if (!on) {
2995 		printf("%s: 0x%08x\n", __func__, idx);
2996 		return;
2997 	}
2998 
2999 	switch (idx) {
3000 	case RK3399_CLK_USB2PHY0_REF:
3001 		HWRITE4(sc, RK3399_CRU_CLKGATE_CON(6), (1 << 5) << 16);
3002 		break;
3003 	case RK3399_CLK_USB2PHY1_REF:
3004 		HWRITE4(sc, RK3399_CRU_CLKGATE_CON(6), (1 << 6) << 16);
3005 		break;
3006 	case RK3399_CLK_UPHY0_TCPDPHY_REF:
3007 		HWRITE4(sc, RK3399_CRU_CLKGATE_CON(13), (1 << 4) << 16);
3008 		break;
3009 	case RK3399_CLK_UPHY0_TCPDCORE:
3010 		HWRITE4(sc, RK3399_CRU_CLKGATE_CON(13), (1 << 5) << 16);
3011 		break;
3012 	case RK3399_CLK_UPHY1_TCPDPHY_REF:
3013 		HWRITE4(sc, RK3399_CRU_CLKGATE_CON(13), (1 << 6) << 16);
3014 		break;
3015 	case RK3399_CLK_UPHY1_TCPDCORE:
3016 		HWRITE4(sc, RK3399_CRU_CLKGATE_CON(13), (1 << 7) << 16);
3017 		break;
3018 	case RK3399_ACLK_GMAC:
3019 		HWRITE4(sc, RK3399_CRU_CLKGATE_CON(32), (1 << 0) << 16);
3020 		break;
3021 	case RK3399_PCLK_GMAC:
3022 		HWRITE4(sc, RK3399_CRU_CLKGATE_CON(32), (1 << 2) << 16);
3023 		break;
3024 	case RK3399_CLK_MAC:
3025 		HWRITE4(sc, RK3399_CRU_CLKGATE_CON(5), (1 << 5) << 16);
3026 		break;
3027 	case RK3399_CLK_MAC_RX:
3028 		HWRITE4(sc, RK3399_CRU_CLKGATE_CON(5), (1 << 8) << 16);
3029 		break;
3030 	case RK3399_CLK_MAC_TX:
3031 		HWRITE4(sc, RK3399_CRU_CLKGATE_CON(5), (1 << 9) << 16);
3032 		break;
3033 	}
3034 }
3035 
3036 void
rk3399_reset(void * cookie,uint32_t * cells,int on)3037 rk3399_reset(void *cookie, uint32_t *cells, int on)
3038 {
3039 	struct rkclock_softc *sc = cookie;
3040 	uint32_t idx = cells[0];
3041 	uint32_t mask = (1 << (idx % 16));
3042 
3043 	HWRITE4(sc, RK3399_CRU_SOFTRST_CON(idx / 16),
3044 	    mask << 16 | (on ? mask : 0));
3045 }
3046 
3047 /* PMUCRU */
3048 
3049 const struct rkclock rk3399_pmu_clocks[] = {
3050 	{
3051 		RK3399_CLK_I2C0, RK3399_PMUCRU_CLKSEL_CON(2),
3052 		0, DIV(6, 0),
3053 		{ RK3399_PLL_PPLL }
3054 	},
3055 	{
3056 		RK3399_CLK_I2C4, RK3399_PMUCRU_CLKSEL_CON(3),
3057 		0, DIV(6, 0),
3058 		{ RK3399_PLL_PPLL }
3059 	},
3060 	{
3061 		RK3399_CLK_I2C8, RK3399_PMUCRU_CLKSEL_CON(2),
3062 		0, DIV(14, 8),
3063 		{ RK3399_PLL_PPLL }
3064 	},
3065 	{
3066 		RK3399_PCLK_RKPWM, RK3399_PMUCRU_CLKSEL_CON(0),
3067 		0, DIV(6, 0),
3068 		{ RK3399_PLL_PPLL }
3069 	},
3070 	{
3071 		/* Sentinel */
3072 	}
3073 };
3074 
3075 void
rk3399_pmu_init(struct rkclock_softc * sc)3076 rk3399_pmu_init(struct rkclock_softc *sc)
3077 {
3078 	sc->sc_clocks = rk3399_pmu_clocks;
3079 	rk3399_pmucru_sc = sc;
3080 }
3081 
3082 uint32_t
rk3399_pmu_get_frequency(void * cookie,uint32_t * cells)3083 rk3399_pmu_get_frequency(void *cookie, uint32_t *cells)
3084 {
3085 	struct rkclock_softc *sc = cookie;
3086 	uint32_t idx = cells[0];
3087 
3088 	switch (idx) {
3089 	case RK3399_PLL_PPLL:
3090 		return rk3399_get_pll(sc, RK3399_PMUCRU_PPLL_CON(0));
3091 	default:
3092 		break;
3093 	}
3094 
3095 	return rkclock_get_frequency(sc, idx);
3096 }
3097 
3098 int
rk3399_pmu_set_frequency(void * cookie,uint32_t * cells,uint32_t freq)3099 rk3399_pmu_set_frequency(void *cookie, uint32_t *cells, uint32_t freq)
3100 {
3101 	struct rkclock_softc *sc = cookie;
3102 	uint32_t idx = cells[0];
3103 
3104 	switch (idx) {
3105 	case RK3399_PLL_PPLL:
3106 		return rk3399_set_pll(sc, RK3399_PMUCRU_PPLL_CON(0), freq);
3107 	default:
3108 		break;
3109 	}
3110 
3111 	return rkclock_set_frequency(sc, idx, freq);
3112 }
3113 
3114 void
rk3399_pmu_enable(void * cookie,uint32_t * cells,int on)3115 rk3399_pmu_enable(void *cookie, uint32_t *cells, int on)
3116 {
3117 	uint32_t idx = cells[0];
3118 
3119 	switch (idx) {
3120 	case RK3399_CLK_I2C0:
3121 	case RK3399_CLK_I2C4:
3122 	case RK3399_CLK_I2C8:
3123 	case RK3399_PCLK_I2C0:
3124 	case RK3399_PCLK_I2C4:
3125 	case RK3399_PCLK_I2C8:
3126 	case RK3399_PCLK_RKPWM:
3127 		/* Enabled by default. */
3128 		break;
3129 	default:
3130 		printf("%s: 0x%08x\n", __func__, idx);
3131 		break;
3132 	}
3133 }
3134 
3135 void
rk3399_pmu_reset(void * cookie,uint32_t * cells,int on)3136 rk3399_pmu_reset(void *cookie, uint32_t *cells, int on)
3137 {
3138 	uint32_t idx = cells[0];
3139 
3140 	printf("%s: 0x%08x\n", __func__, idx);
3141 }
3142 
3143 /*
3144  * Rockchip RK3568
3145  */
3146 
3147 const struct rkclock rk3568_clocks[] = {
3148 	{
3149 		RK3568_BCLK_EMMC, RK3568_CRU_CLKSEL_CON(28),
3150 		SEL(9, 8), 0,
3151 		{ RK3568_GPLL_200M, RK3568_GPLL_150M, RK3568_CPLL_125M }
3152 	},
3153 	{
3154 		RK3568_CCLK_EMMC, RK3568_CRU_CLKSEL_CON(28),
3155 		SEL(14, 12), 0,
3156 		{ RK3568_XIN24M, RK3568_GPLL_200M, RK3568_GPLL_150M,
3157 		  RK3568_CPLL_100M, RK3568_CPLL_50M, RK3568_CLK_OSC0_DIV_375K }
3158 	},
3159 	{
3160 		RK3568_TCLK_EMMC, 0, 0, 0,
3161 		{ RK3568_XIN24M }
3162 	},
3163 
3164 	{
3165 		RK3568_ACLK_PHP, RK3568_CRU_CLKSEL_CON(30),
3166 		SEL(1, 0), 0,
3167 		{ RK3568_GPLL_300M, RK3568_GPLL_200M,
3168 		  RK3568_GPLL_100M, RK3568_XIN24M }
3169 	},
3170 	{
3171 		RK3568_PCLK_PHP, RK3568_CRU_CLKSEL_CON(30),
3172 		0, DIV(7, 4),
3173 		{ RK3568_ACLK_PHP }
3174 	},
3175 	{
3176 		RK3568_CLK_SDMMC0, RK3568_CRU_CLKSEL_CON(30),
3177 		SEL(10, 8), 0,
3178 		{ RK3568_XIN24M, RK3568_GPLL_400M, RK3568_GPLL_300M,
3179 		  RK3568_CPLL_100M, RK3568_CPLL_50M, RK3568_CLK_OSC0_DIV_750K }
3180 	},
3181 	{
3182 		RK3568_CLK_SDMMC1, RK3568_CRU_CLKSEL_CON(30),
3183 		SEL(14, 12), 0,
3184 		{ RK3568_XIN24M, RK3568_GPLL_400M, RK3568_GPLL_300M,
3185 		  RK3568_CPLL_100M, RK3568_CPLL_50M, RK3568_CLK_OSC0_DIV_750K }
3186 	},
3187 	{
3188 		RK3568_CLK_SDMMC2, RK3568_CRU_CLKSEL_CON(32),
3189 		SEL(10, 8), 0,
3190 		{ RK3568_XIN24M, RK3568_GPLL_400M, RK3568_GPLL_300M,
3191 		  RK3568_CPLL_100M, RK3568_CPLL_50M, RK3568_CLK_OSC0_DIV_750K }
3192 	},
3193 	{
3194 		RK3568_ACLK_GMAC0, 0, 0, 0,
3195 		{ RK3568_ACLK_PHP }
3196 	},
3197 	{
3198 		RK3568_PCLK_GMAC0, 0, 0, 0,
3199 		{ RK3568_PCLK_PHP }
3200 	},
3201 	{
3202 		RK3568_CLK_MAC0_2TOP, RK3568_CRU_CLKSEL_CON(31),
3203 		SEL(9, 8), 0,
3204 		{ RK3568_CPLL_125M, RK3568_CPLL_50M,
3205 		  RK3568_CPLL_25M, RK3568_XIN24M }
3206 	},
3207 	{
3208 		RK3568_CLK_MAC0_REFOUT, 0, 0, 0,
3209 		{ RK3568_CLK_MAC0_2TOP }
3210 	},
3211 	{
3212 		RK3568_CLK_GMAC0_PTP_REF, RK3568_CRU_CLKSEL_CON(31),
3213 		SEL(13, 12), 0,
3214 		{ RK3568_CPLL_62P5M, RK3568_GPLL_100M,
3215 		  RK3568_CPLL_50M, RK3568_XIN24M }
3216 	},
3217 	{
3218 		RK3568_ACLK_USB, RK3568_CRU_CLKSEL_CON(32),
3219 		SEL(1, 0), 0,
3220 		{ RK3568_GPLL_300M, RK3568_GPLL_200M,
3221 		  RK3568_GPLL_100M, RK3568_XIN24M }
3222 	},
3223 	{
3224 		RK3568_PCLK_USB, RK3568_CRU_CLKSEL_CON(32),
3225 		0, DIV(7, 4),
3226 		{ RK3568_ACLK_USB }
3227 	},
3228 	{
3229 		RK3568_ACLK_GMAC1, 0, 0, 0,
3230 		{ RK3568_ACLK_USB }
3231 	},
3232 	{
3233 		RK3568_PCLK_GMAC1, 0, 0, 0,
3234 		{ RK3568_PCLK_USB }
3235 	},
3236 	{
3237 		RK3568_CLK_MAC1_2TOP, RK3568_CRU_CLKSEL_CON(33),
3238 		SEL(9, 8), 0,
3239 		{ RK3568_CPLL_125M, RK3568_CPLL_50M,
3240 		  RK3568_CPLL_25M, RK3568_XIN24M }
3241 	},
3242 	{
3243 		RK3568_CLK_MAC1_REFOUT, 0, 0, 0,
3244 		{ RK3568_CLK_MAC1_2TOP }
3245 	},
3246 	{
3247 		RK3568_CLK_GMAC1_PTP_REF, RK3568_CRU_CLKSEL_CON(33),
3248 		SEL(13, 12), 0,
3249 		{ RK3568_CPLL_62P5M, RK3568_GPLL_100M,
3250 		  RK3568_CPLL_50M, RK3568_XIN24M }
3251 	},
3252 	{
3253 		RK3568_CLK_TSADC_TSEN, RK3568_CRU_CLKSEL_CON(51),
3254 		SEL(5, 4), DIV(2, 0),
3255 		{ RK3568_XIN24M, RK3568_GPLL_100M, RK3568_CPLL_100M }
3256 	},
3257 	{
3258 		RK3568_CLK_TSADC, RK3568_CRU_CLKSEL_CON(51),
3259 		0, DIV(14, 8),
3260 		{ RK3568_CLK_TSADC_TSEN }
3261 	},
3262 	{
3263 		RK3568_SCLK_UART1, RK3568_CRU_CLKSEL_CON(52),
3264 		SEL(13, 12), 0,
3265 		{ 0, 0, RK3568_XIN24M }
3266 	},
3267 	{
3268 		RK3568_SCLK_UART2, RK3568_CRU_CLKSEL_CON(54),
3269 		SEL(13, 12), 0,
3270 		{ 0, 0, RK3568_XIN24M }
3271 	},
3272 	{
3273 		RK3568_SCLK_UART3, RK3568_CRU_CLKSEL_CON(56),
3274 		SEL(13, 12), 0,
3275 		{ 0, 0, RK3568_XIN24M }
3276 	},
3277 	{
3278 		RK3568_SCLK_UART4, RK3568_CRU_CLKSEL_CON(58),
3279 		SEL(13, 12), 0,
3280 		{ 0, 0, RK3568_XIN24M }
3281 	},
3282 	{
3283 		RK3568_SCLK_UART5, RK3568_CRU_CLKSEL_CON(60),
3284 		SEL(13, 12), 0,
3285 		{ 0, 0, RK3568_XIN24M }
3286 	},
3287 	{
3288 		RK3568_SCLK_UART6, RK3568_CRU_CLKSEL_CON(62),
3289 		SEL(13, 12), 0,
3290 		{ 0, 0, RK3568_XIN24M }
3291 	},
3292 	{
3293 		RK3568_SCLK_UART7, RK3568_CRU_CLKSEL_CON(64),
3294 		SEL(13, 12), 0,
3295 		{ 0, 0, RK3568_XIN24M }
3296 	},
3297 	{
3298 		RK3568_SCLK_UART8, RK3568_CRU_CLKSEL_CON(66),
3299 		SEL(13, 12), 0,
3300 		{ 0, 0, RK3568_XIN24M }
3301 	},
3302 	{
3303 		RK3568_SCLK_UART9, RK3568_CRU_CLKSEL_CON(68),
3304 		SEL(13, 12), 0,
3305 		{ 0, 0, RK3568_XIN24M }
3306 	},
3307 	{
3308 		RK3568_CLK_I2C, RK3568_CRU_CLKSEL_CON(71),
3309 		SEL(9, 8), 0,
3310 		{ 0, 0, RK3568_XIN24M }
3311 	},
3312 	{
3313 		RK3568_CLK_I2C1, 0, 0, 0,
3314 		{ RK3568_CLK_I2C }
3315 	},
3316 	{
3317 		RK3568_CLK_I2C2, 0, 0, 0,
3318 		{ RK3568_CLK_I2C }
3319 	},
3320 	{
3321 		RK3568_CLK_I2C3, 0, 0, 0,
3322 		{ RK3568_CLK_I2C }
3323 	},
3324 	{
3325 		RK3568_CLK_I2C4, 0, 0, 0,
3326 		{ RK3568_CLK_I2C }
3327 	},
3328 	{
3329 		RK3568_CLK_I2C5, 0, 0, 0,
3330 		{ RK3568_CLK_I2C }
3331 	},
3332 	{
3333 		RK3568_CLK_SPI0, RK3568_CRU_CLKSEL_CON(72),
3334 		SEL(1, 0), 0,
3335 		{ RK3568_GPLL_200M, RK3568_XIN24M, RK3568_CPLL_100M }
3336 	},
3337 	{
3338 		RK3568_CLK_SPI1, RK3568_CRU_CLKSEL_CON(72),
3339 		SEL(3, 2), 0,
3340 		{ RK3568_GPLL_200M, RK3568_XIN24M, RK3568_CPLL_100M }
3341 	},
3342 	{
3343 		RK3568_CLK_SPI2, RK3568_CRU_CLKSEL_CON(72),
3344 		SEL(5, 4), 0,
3345 		{ RK3568_GPLL_200M, RK3568_XIN24M, RK3568_CPLL_100M }
3346 	},
3347 	{
3348 		RK3568_CLK_SPI3, RK3568_CRU_CLKSEL_CON(72),
3349 		SEL(7, 6), 0,
3350 		{ RK3568_GPLL_200M, RK3568_XIN24M, RK3568_CPLL_100M }
3351 	},
3352 	{
3353 		RK3568_SCLK_GMAC0, RK3568_CRU_CLKSEL_CON(31),
3354 		SEL(2, 2), 0,
3355 		{ RK3568_CLK_MAC0_2TOP, RK3568_GMAC0_CLKIN }
3356 	},
3357 	{
3358 		RK3568_SCLK_GMAC0_RGMII_SPEED, RK3568_CRU_CLKSEL_CON(31),
3359 		SEL(5, 4), 0,
3360 		{ RK3568_SCLK_GMAC0, RK3568_SCLK_GMAC0,
3361 		  RK3568_SCLK_GMAC0_DIV_50, RK3568_SCLK_GMAC0_DIV_5 }
3362 	},
3363 	{
3364 		RK3568_SCLK_GMAC0_RMII_SPEED, RK3568_CRU_CLKSEL_CON(31),
3365 		SEL(3, 3), 0,
3366 		{ RK3568_SCLK_GMAC0_DIV_20, RK3568_SCLK_GMAC0_DIV_2 }
3367 	},
3368 	{
3369 		RK3568_SCLK_GMAC0_RX_TX, RK3568_CRU_CLKSEL_CON(31),
3370 		SEL(1, 0), 0,
3371 		{ RK3568_SCLK_GMAC0_RGMII_SPEED, RK3568_SCLK_GMAC0_RMII_SPEED }
3372 	},
3373 	{
3374 		RK3568_SCLK_GMAC1, RK3568_CRU_CLKSEL_CON(33),
3375 		SEL(2, 2), 0,
3376 		{ RK3568_CLK_MAC1_2TOP, RK3568_GMAC1_CLKIN }
3377 	},
3378 	{
3379 		RK3568_SCLK_GMAC1_RGMII_SPEED, RK3568_CRU_CLKSEL_CON(33),
3380 		SEL(5, 4), 0,
3381 		{ RK3568_SCLK_GMAC1, RK3568_SCLK_GMAC1,
3382 		  RK3568_SCLK_GMAC1_DIV_50, RK3568_SCLK_GMAC1_DIV_5 }
3383 	},
3384 	{
3385 		RK3568_SCLK_GMAC1_RMII_SPEED, RK3568_CRU_CLKSEL_CON(33),
3386 		SEL(3, 3), 0,
3387 		{ RK3568_SCLK_GMAC1_DIV_20, RK3568_SCLK_GMAC1_DIV_2 }
3388 	},
3389 	{
3390 		RK3568_SCLK_GMAC1_RX_TX, RK3568_CRU_CLKSEL_CON(33),
3391 		SEL(1, 0), 0,
3392 		{ RK3568_SCLK_GMAC1_RGMII_SPEED, RK3568_SCLK_GMAC1_RMII_SPEED }
3393 	},
3394 	{
3395 		RK3568_CPLL_125M, RK3568_CRU_CLKSEL_CON(80),
3396 		0, DIV(4, 0),
3397 		{ RK3568_PLL_CPLL }
3398 	},
3399 	{
3400 		RK3568_CPLL_62P5M, RK3568_CRU_CLKSEL_CON(80),
3401 		0, DIV(12, 8),
3402 		{ RK3568_PLL_CPLL }
3403 	},
3404 	{
3405 		RK3568_CPLL_50M, RK3568_CRU_CLKSEL_CON(81),
3406 		0, DIV(4, 0),
3407 		{ RK3568_PLL_CPLL }
3408 	},
3409 	{
3410 		RK3568_CPLL_25M, RK3568_CRU_CLKSEL_CON(81),
3411 		0, DIV(13, 8),
3412 		{ RK3568_PLL_CPLL }
3413 	},
3414 	{
3415 		RK3568_CPLL_100M, RK3568_CRU_CLKSEL_CON(82),
3416 		0, DIV(4, 0),
3417 		{ RK3568_PLL_CPLL }
3418 	},
3419 	{
3420 		RK3568_GPLL_400M, RK3568_CRU_CLKSEL_CON(75),
3421 		0, DIV(4, 0),
3422 		{ RK3568_PLL_GPLL }
3423 	},
3424 	{
3425 		RK3568_GPLL_300M, RK3568_CRU_CLKSEL_CON(75),
3426 		0, DIV(12, 8),
3427 		{ RK3568_PLL_GPLL }
3428 	},
3429 	{
3430 		RK3568_GPLL_200M, RK3568_CRU_CLKSEL_CON(76),
3431 		0, DIV(4, 0),
3432 		{ RK3568_PLL_GPLL }
3433 	},
3434 	{
3435 		RK3568_GPLL_150M, RK3568_CRU_CLKSEL_CON(76),
3436 		0, DIV(12, 5),
3437 		{ RK3568_PLL_GPLL }
3438 	},
3439 	{
3440 		RK3568_GPLL_100M, RK3568_CRU_CLKSEL_CON(77),
3441 		0, DIV(4, 0),
3442 		{ RK3568_PLL_GPLL }
3443 	},
3444 	{
3445 		RK3568_CLK_OSC0_DIV_750K, RK3568_CRU_CLKSEL_CON(82),
3446 		0, DIV(13, 8),
3447 		{ RK3568_XIN24M }
3448 	},
3449 	{
3450 		/* Sentinel */
3451 	}
3452 };
3453 
3454 void
rk3568_init(struct rkclock_softc * sc)3455 rk3568_init(struct rkclock_softc *sc)
3456 {
3457 	int i;
3458 
3459 	/* The code below assumes all clocks are enabled.  Check this!. */
3460 	for (i = 0; i <= 35; i++) {
3461 		if (HREAD4(sc, RK3568_CRU_GATE_CON(i)) != 0x00000000) {
3462 			printf("CRU_GATE_CON%d: 0x%08x\n", i,
3463 			    HREAD4(sc, RK3568_CRU_GATE_CON(i)));
3464 		}
3465 	}
3466 
3467 	sc->sc_clocks = rk3568_clocks;
3468 }
3469 
3470 int
rk3568_set_pll(struct rkclock_softc * sc,bus_size_t base,uint32_t freq)3471 rk3568_set_pll(struct rkclock_softc *sc, bus_size_t base, uint32_t freq)
3472 {
3473 	uint32_t fbdiv, postdiv1, postdiv2, refdiv;
3474 	int mode_shift = -1;
3475 
3476 	switch (base) {
3477 	case RK3568_CRU_APLL_CON(0):
3478 		mode_shift = 0;
3479 		break;
3480 	case RK3568_CRU_DPLL_CON(0):
3481 		mode_shift = 2;
3482 		break;
3483 	case RK3568_CRU_CPLL_CON(0):
3484 		mode_shift = 4;
3485 		break;
3486 	case RK3568_CRU_GPLL_CON(0):
3487 		mode_shift = 6;
3488 		break;
3489 	case RK3568_CRU_NPLL_CON(0):
3490 		mode_shift = 10;
3491 		break;
3492 	case RK3568_CRU_VPLL_CON(0):
3493 		mode_shift = 12;
3494 		break;
3495 	}
3496 	KASSERT(mode_shift != -1);
3497 
3498 	/*
3499 	 * It is not clear whether all combinations of the clock
3500 	 * dividers result in a stable clock.  Therefore this function
3501 	 * only supports a limited set of PLL clock rates.
3502 	 */
3503 	switch (freq) {
3504 	case 1200000000U:
3505 		postdiv1 = 2; postdiv2 = refdiv = 1;
3506 		break;
3507 	default:
3508 		printf("%s: %u Hz\n", __func__, freq);
3509 		return -1;
3510 	}
3511 
3512 	/* Calculate feedback divider. */
3513 	fbdiv = freq * postdiv1 * postdiv2 * refdiv / 24000000;
3514 
3515 	/*
3516 	 * Select slow mode to guarantee a stable clock while we're
3517 	 * adjusting the PLL.
3518 	 */
3519 	HWRITE4(sc, RK3568_CRU_MODE_CON,
3520 	   (RK3328_CRU_CRU_MODE_MASK << 16 |
3521 	   RK3328_CRU_CRU_MODE_SLOW) << mode_shift);
3522 
3523 	/* Set PLL rate. */
3524 	HWRITE4(sc, base + 0x0000,
3525 	    RK3328_CRU_PLL_POSTDIV1_MASK << 16 |
3526 	    postdiv1 << RK3328_CRU_PLL_POSTDIV1_SHIFT |
3527 	    RK3328_CRU_PLL_FBDIV_MASK << 16 |
3528 	    fbdiv << RK3328_CRU_PLL_FBDIV_SHIFT);
3529 	HWRITE4(sc, base + 0x0004,
3530 	    RK3328_CRU_PLL_DSMPD << 16 | RK3328_CRU_PLL_DSMPD |
3531 	    RK3328_CRU_PLL_POSTDIV2_MASK << 16 |
3532 	    postdiv2 << RK3328_CRU_PLL_POSTDIV2_SHIFT |
3533 	    RK3328_CRU_PLL_REFDIV_MASK << 16 |
3534 	    refdiv << RK3328_CRU_PLL_REFDIV_SHIFT);
3535 
3536 	/* Wait for PLL to stabilize. */
3537 	while ((HREAD4(sc, base + 0x0004) & RK3328_CRU_PLL_PLL_LOCK) == 0)
3538 		delay(10);
3539 
3540 	/* Switch back to normal mode. */
3541 	HWRITE4(sc, RK3568_CRU_MODE_CON,
3542 	   (RK3328_CRU_CRU_MODE_MASK << 16 |
3543 	   RK3328_CRU_CRU_MODE_NORMAL) << mode_shift);
3544 
3545 	return 0;
3546 }
3547 
3548 uint32_t
rk3568_get_frequency(void * cookie,uint32_t * cells)3549 rk3568_get_frequency(void *cookie, uint32_t *cells)
3550 {
3551 	struct rkclock_softc *sc = cookie;
3552 	uint32_t idx = cells[0];
3553 
3554 	switch (idx) {
3555 	case RK3568_PLL_APLL:
3556 		return rk3328_get_pll(sc, RK3568_CRU_APLL_CON(0));
3557 	case RK3568_PLL_DPLL:
3558 		return rk3328_get_pll(sc, RK3568_CRU_DPLL_CON(0));
3559 	case RK3568_PLL_CPLL:
3560 		return rk3328_get_pll(sc, RK3568_CRU_CPLL_CON(0));
3561 	case RK3568_PLL_GPLL:
3562 		return rk3328_get_pll(sc, RK3568_CRU_GPLL_CON(0));
3563 	case RK3568_PLL_NPLL:
3564 		return rk3328_get_pll(sc, RK3568_CRU_NPLL_CON(0));
3565 	case RK3568_PLL_VPLL:
3566 		return rk3328_get_pll(sc, RK3568_CRU_VPLL_CON(0));
3567 	case RK3568_SCLK_GMAC0_DIV_50:
3568 		idx = RK3568_SCLK_GMAC0;
3569 		return rk3568_get_frequency(sc, &idx) / 50;
3570 	case RK3568_SCLK_GMAC0_DIV_5:
3571 		idx = RK3568_SCLK_GMAC0;
3572 		return rk3568_get_frequency(sc, &idx) / 5;
3573 	case RK3568_SCLK_GMAC0_DIV_20:
3574 		idx = RK3568_SCLK_GMAC0;
3575 		return rk3568_get_frequency(sc, &idx) / 20;
3576 	case RK3568_SCLK_GMAC0_DIV_2:
3577 		idx = RK3568_SCLK_GMAC0;
3578 		return rk3568_get_frequency(sc, &idx) / 2;
3579 	case RK3568_SCLK_GMAC1_DIV_50:
3580 		idx = RK3568_SCLK_GMAC1;
3581 		return rk3568_get_frequency(sc, &idx) / 50;
3582 	case RK3568_SCLK_GMAC1_DIV_5:
3583 		idx = RK3568_SCLK_GMAC1;
3584 		return rk3568_get_frequency(sc, &idx) / 5;
3585 	case RK3568_SCLK_GMAC1_DIV_20:
3586 		idx = RK3568_SCLK_GMAC1;
3587 		return rk3568_get_frequency(sc, &idx) / 20;
3588 	case RK3568_SCLK_GMAC1_DIV_2:
3589 		idx = RK3568_SCLK_GMAC1;
3590 		return rk3568_get_frequency(sc, &idx) / 2;
3591 	case RK3568_CLK_OSC0_DIV_375K:
3592 		idx = RK3568_CLK_OSC0_DIV_750K;
3593 		return rk3568_get_frequency(sc, &idx) / 2;
3594 	case RK3568_GMAC0_CLKIN:
3595 		return rkclock_external_frequency("gmac0_clkin");
3596 	case RK3568_GMAC1_CLKIN:
3597 		return rkclock_external_frequency("gmac1_clkin");
3598 	case RK3568_XIN24M:
3599 		return 24000000;
3600 	default:
3601 		break;
3602 	}
3603 
3604 	return rkclock_get_frequency(sc, idx);
3605 }
3606 
3607 int
rk3568_set_frequency(void * cookie,uint32_t * cells,uint32_t freq)3608 rk3568_set_frequency(void *cookie, uint32_t *cells, uint32_t freq)
3609 {
3610 	struct rkclock_softc *sc = cookie;
3611 	uint32_t idx = cells[0];
3612 
3613 	switch (idx) {
3614 	case RK3568_PLL_GPLL:
3615 		return rk3568_set_pll(sc, RK3568_CRU_GPLL_CON(0), freq);
3616 	default:
3617 		break;
3618 	}
3619 
3620 	return rkclock_set_frequency(sc, idx, freq);
3621 }
3622 
3623 int
rk3568_set_parent(void * cookie,uint32_t * cells,uint32_t * pcells)3624 rk3568_set_parent(void *cookie, uint32_t *cells, uint32_t *pcells)
3625 {
3626 	struct rkclock_softc *sc = cookie;
3627 	char buf[64] = {};
3628 	int len, node;
3629 
3630 	if (pcells[0] != sc->sc_phandle) {
3631 		node = OF_getnodebyphandle(pcells[0]);
3632 		if (node == 0)
3633 			return -1;
3634 		len = OF_getproplen(node, "clock-output-names");
3635 		if (len <= 0 || len > sizeof(buf))
3636 			return -1;
3637 		OF_getprop(node, "clock-output-names", buf, sizeof(buf));
3638 
3639 		if (strcmp(buf, "gmac0_clkin") == 0) {
3640 			return rkclock_set_parent(sc, cells[0],
3641 			    RK3568_GMAC0_CLKIN);
3642 		}
3643 		if (strcmp(buf, "gmac1_clkin") == 0) {
3644 			return rkclock_set_parent(sc, cells[0],
3645 			    RK3568_GMAC1_CLKIN);
3646 		}
3647 
3648 		printf("%s: 0x%08x 0x%08x\n", __func__, cells[0], pcells[0]);
3649 		return -1;
3650 	}
3651 
3652 	return rkclock_set_parent(sc, cells[0], pcells[1]);
3653 }
3654 
3655 void
rk3568_enable(void * cookie,uint32_t * cells,int on)3656 rk3568_enable(void *cookie, uint32_t *cells, int on)
3657 {
3658 	uint32_t idx = cells[0];
3659 
3660 	/* All clocks are enabled upon hardware reset. */
3661 	if (!on) {
3662 		printf("%s: 0x%08x\n", __func__, idx);
3663 		return;
3664 	}
3665 }
3666 
3667 void
rk3568_reset(void * cookie,uint32_t * cells,int on)3668 rk3568_reset(void *cookie, uint32_t *cells, int on)
3669 {
3670 	struct rkclock_softc *sc = cookie;
3671 	uint32_t idx = cells[0];
3672 	uint32_t mask = (1 << (idx % 16));
3673 
3674 	HWRITE4(sc, RK3568_CRU_SOFTRST_CON(idx / 16),
3675 	    mask << 16 | (on ? mask : 0));
3676 }
3677 
3678 /* PMUCRU */
3679 
3680 const struct rkclock rk3568_pmu_clocks[] = {
3681 	{
3682 		RK3568_CLK_RTC_32K, RK3568_PMUCRU_CLKSEL_CON(0),
3683 		SEL(7, 6), 0,
3684 		{ 0, RK3568_XIN32K, RK3568_CLK_RTC32K_FRAC },
3685 		SET_PARENT
3686 	},
3687 	{
3688 		RK3568_CLK_I2C0, RK3568_PMUCRU_CLKSEL_CON(3),
3689 		0, DIV(15, 7),
3690 		{ RK3568_CLK_PDPMU }
3691 	},
3692 	{
3693 		RK3568_SCLK_UART0, RK3568_PMUCRU_CLKSEL_CON(4),
3694 		SEL(11, 10), 0,
3695 		{ 0, 0, RK3568_XIN24M }
3696 	},
3697 	{
3698 		RK3568_CLK_PCIEPHY0_OSC0, 0, 0, 0,
3699 		{ RK3568_XIN24M }
3700 	},
3701 	{
3702 		RK3568_CLK_PCIEPHY0_DIV, RK3568_PMUCRU_CLKSEL_CON(9),
3703 		0, DIV(2, 0),
3704 		{ RK3568_PPLL_PH0 }
3705 	},
3706 	{
3707 		RK3568_CLK_PCIEPHY0_REF, RK3568_PMUCRU_CLKSEL_CON(9),
3708 		SEL(3, 3), 0,
3709 		{ RK3568_CLK_PCIEPHY0_OSC0, RK3568_CLK_PCIEPHY0_DIV },
3710 		SET_PARENT
3711 	},
3712 	{
3713 		RK3568_CLK_PCIEPHY1_OSC0, 0, 0, 0,
3714 		{ RK3568_XIN24M }
3715 	},
3716 	{
3717 		RK3568_CLK_PCIEPHY1_DIV, RK3568_PMUCRU_CLKSEL_CON(9),
3718 		0, DIV(6, 4),
3719 		{ RK3568_PPLL_PH0 }
3720 	},
3721 	{
3722 		RK3568_CLK_PCIEPHY1_REF, RK3568_PMUCRU_CLKSEL_CON(9),
3723 		SEL(7, 7), 0,
3724 		{ RK3568_CLK_PCIEPHY1_OSC0, RK3568_CLK_PCIEPHY1_DIV },
3725 		SET_PARENT
3726 	},
3727 	{
3728 		RK3568_CLK_PCIEPHY2_OSC0, 0, 0, 0,
3729 		{ RK3568_XIN24M }
3730 	},
3731 	{
3732 		RK3568_CLK_PCIEPHY2_DIV, RK3568_PMUCRU_CLKSEL_CON(9),
3733 		0, DIV(10, 8),
3734 		{ RK3568_PPLL_PH0 }
3735 	},
3736 	{
3737 		RK3568_CLK_PCIEPHY2_REF, RK3568_PMUCRU_CLKSEL_CON(9),
3738 		SEL(11, 11), 0,
3739 		{ RK3568_CLK_PCIEPHY2_OSC0, RK3568_CLK_PCIEPHY2_DIV },
3740 		SET_PARENT
3741 	},
3742 	{
3743 		RK3568_CLK_PDPMU, RK3568_PMUCRU_CLKSEL_CON(2),
3744 		SEL(15, 15), 0,
3745 		{ RK3568_PLL_PPLL, 0 }
3746 	},
3747 	{
3748 		/* Sentinel */
3749 	}
3750 };
3751 
3752 void
rk3568_pmu_init(struct rkclock_softc * sc)3753 rk3568_pmu_init(struct rkclock_softc *sc)
3754 {
3755 	int i;
3756 
3757 	/* The code below assumes all clocks are enabled.  Check this!. */
3758 	for (i = 0; i <= 2; i++) {
3759 		if (HREAD4(sc, RK3568_PMUCRU_GATE_CON(i)) != 0x00000000) {
3760 			printf("CRU_GATE_CON%d: 0x%08x\n", i,
3761 			    HREAD4(sc, RK3568_CRU_GATE_CON(i)));
3762 		}
3763 	}
3764 
3765 	sc->sc_clocks = rk3568_pmu_clocks;
3766 }
3767 
3768 int
rk3568_pmu_set_pll(struct rkclock_softc * sc,bus_size_t base,uint32_t freq)3769 rk3568_pmu_set_pll(struct rkclock_softc *sc, bus_size_t base, uint32_t freq)
3770 {
3771 	uint32_t fbdiv, postdiv1, postdiv2, refdiv;
3772 	int mode_shift = -1;
3773 
3774 	switch (base) {
3775 	case RK3568_PMUCRU_PPLL_CON(0):
3776 		mode_shift = 0;
3777 		break;
3778 	case RK3568_PMUCRU_HPLL_CON(0):
3779 		mode_shift = 2;
3780 		break;
3781 	}
3782 	KASSERT(mode_shift != -1);
3783 
3784 	/*
3785 	 * It is not clear whether all combinations of the clock
3786 	 * dividers result in a stable clock.  Therefore this function
3787 	 * only supports a limited set of PLL clock rates.
3788 	 */
3789 	switch (freq) {
3790 	case 200000000U:
3791 		postdiv1 = 3; postdiv2 = 4; refdiv = 1;
3792 		break;
3793 	default:
3794 		printf("%s: %u Hz\n", __func__, freq);
3795 		return -1;
3796 	}
3797 
3798 	/* Calculate feedback divider. */
3799 	fbdiv = freq * postdiv1 * postdiv2 * refdiv / 24000000;
3800 
3801 	/*
3802 	 * Select slow mode to guarantee a stable clock while we're
3803 	 * adjusting the PLL.
3804 	 */
3805 	HWRITE4(sc, RK3568_PMUCRU_MODE_CON,
3806 	   (RK3328_CRU_CRU_MODE_MASK << 16 |
3807 	   RK3328_CRU_CRU_MODE_SLOW) << mode_shift);
3808 
3809 	/* Set PLL rate. */
3810 	HWRITE4(sc, base + 0x0000,
3811 	    RK3328_CRU_PLL_POSTDIV1_MASK << 16 |
3812 	    postdiv1 << RK3328_CRU_PLL_POSTDIV1_SHIFT |
3813 	    RK3328_CRU_PLL_FBDIV_MASK << 16 |
3814 	    fbdiv << RK3328_CRU_PLL_FBDIV_SHIFT);
3815 	HWRITE4(sc, base + 0x0004,
3816 	    RK3328_CRU_PLL_DSMPD << 16 | RK3328_CRU_PLL_DSMPD |
3817 	    RK3328_CRU_PLL_POSTDIV2_MASK << 16 |
3818 	    postdiv2 << RK3328_CRU_PLL_POSTDIV2_SHIFT |
3819 	    RK3328_CRU_PLL_REFDIV_MASK << 16 |
3820 	    refdiv << RK3328_CRU_PLL_REFDIV_SHIFT);
3821 
3822 	/* Wait for PLL to stabilize. */
3823 	while ((HREAD4(sc, base + 0x0004) & RK3328_CRU_PLL_PLL_LOCK) == 0)
3824 		delay(10);
3825 
3826 	/* Switch back to normal mode. */
3827 	HWRITE4(sc, RK3568_PMUCRU_MODE_CON,
3828 	   (RK3328_CRU_CRU_MODE_MASK << 16 |
3829 	   RK3328_CRU_CRU_MODE_NORMAL) << mode_shift);
3830 
3831 	return 0;
3832 }
3833 
3834 uint32_t
rk3568_pmu_get_frequency(void * cookie,uint32_t * cells)3835 rk3568_pmu_get_frequency(void *cookie, uint32_t *cells)
3836 {
3837 	struct rkclock_softc *sc = cookie;
3838 	uint32_t idx = cells[0];
3839 
3840 	switch (idx) {
3841 	case RK3568_PLL_PPLL:
3842 		return rk3328_get_pll(sc, RK3568_PMUCRU_PPLL_CON(0));
3843 	case RK3568_PLL_HPLL:
3844 		return rk3328_get_pll(sc, RK3568_PMUCRU_HPLL_CON(0));
3845 	case RK3568_CLK_RTC32K_FRAC:
3846 		return rk3399_get_frac(sc, RK3568_XIN24M,
3847 		    RK3568_PMUCRU_CLKSEL_CON(1));
3848 	case RK3568_PPLL_PH0:
3849 		idx = RK3568_PLL_PPLL;
3850 		return rk3568_get_frequency(sc, &idx) / 2;
3851 	case RK3568_XIN32K:
3852 		return 32768;
3853 	case RK3568_XIN24M:
3854 		return 24000000;
3855 	default:
3856 		break;
3857 	}
3858 
3859 	return rkclock_get_frequency(sc, idx);
3860 }
3861 
3862 int
rk3568_pmu_set_frequency(void * cookie,uint32_t * cells,uint32_t freq)3863 rk3568_pmu_set_frequency(void *cookie, uint32_t *cells, uint32_t freq)
3864 {
3865 	struct rkclock_softc *sc = cookie;
3866 	uint32_t idx = cells[0];
3867 
3868 	switch (idx) {
3869 	case RK3568_PLL_PPLL:
3870 		return rk3568_pmu_set_pll(sc, RK3568_PMUCRU_PPLL_CON(0), freq);
3871 	case RK3568_PLL_HPLL:
3872 		return rk3568_pmu_set_pll(sc, RK3568_PMUCRU_HPLL_CON(0), freq);
3873 	case RK3568_CLK_RTC32K_FRAC:
3874 		return rk3399_set_frac(sc, RK3568_XIN24M,
3875 		    RK3568_PMUCRU_CLKSEL_CON(1), freq);
3876 	default:
3877 		break;
3878 	}
3879 
3880 	return rkclock_set_frequency(sc, idx, freq);
3881 }
3882 
3883 void
rk3568_pmu_enable(void * cookie,uint32_t * cells,int on)3884 rk3568_pmu_enable(void *cookie, uint32_t *cells, int on)
3885 {
3886 	uint32_t idx = cells[0];
3887 
3888 	switch (idx) {
3889 	case RK3568_CLK_USBPHY0_REF:
3890 	case RK3568_CLK_USBPHY1_REF:
3891 	case RK3568_CLK_PCIEPHY0_REF:
3892 	case RK3568_CLK_PCIEPHY1_REF:
3893 	case RK3568_CLK_PCIEPHY2_REF:
3894 	case RK3568_CLK_PCIE30PHY_REF_M:
3895 	case RK3568_CLK_PCIE30PHY_REF_N:
3896 	case RK3568_CLK_I2C0:
3897 	case RK3568_SCLK_UART0:
3898 	case RK3568_PCLK_I2C0:
3899 		/* Enabled by default. */
3900 		break;
3901 	default:
3902 		printf("%s: 0x%08x\n", __func__, idx);
3903 		break;
3904 	}
3905 }
3906 
3907 void
rk3568_pmu_reset(void * cookie,uint32_t * cells,int on)3908 rk3568_pmu_reset(void *cookie, uint32_t *cells, int on)
3909 {
3910 	uint32_t idx = cells[0];
3911 
3912 	printf("%s: 0x%08x\n", __func__, idx);
3913 }
3914 
3915 /*
3916  * Rockchip RK3588
3917  */
3918 
3919 const struct rkclock rk3588_clocks[] = {
3920 	{
3921 		RK3588_CLK_PWM1, RK3588_CRU_CLKSEL_CON(59),
3922 		SEL(13, 12), 0,
3923 		{ RK3588_CLK_100M_SRC, RK3588_CLK_50M_SRC, RK3588_XIN24M },
3924 	},
3925 	{
3926 		RK3588_CLK_PWM2, RK3588_CRU_CLKSEL_CON(59),
3927 		SEL(15, 14), 0,
3928 		{ RK3588_CLK_100M_SRC, RK3588_CLK_50M_SRC, RK3588_XIN24M },
3929 	},
3930 	{
3931 		RK3588_CLK_PWM3, RK3588_CRU_CLKSEL_CON(60),
3932 		SEL(1, 0), 0,
3933 		{ RK3588_CLK_100M_SRC, RK3588_CLK_50M_SRC, RK3588_XIN24M },
3934 	},
3935 	{
3936 		RK3588_ACLK_BUS_ROOT, RK3588_CRU_CLKSEL_CON(38),
3937 		SEL(5, 5), DIV(4, 0),
3938 		{ RK3588_PLL_GPLL, RK3588_PLL_CPLL }
3939 	},
3940 	{
3941 		RK3588_CLK_I2C1, RK3588_CRU_CLKSEL_CON(38),
3942 		SEL(6, 6), 0,
3943 		{ RK3588_CLK_200M_SRC , RK3588_CLK_100M_SRC },
3944 	},
3945 	{
3946 		RK3588_CLK_I2C2, RK3588_CRU_CLKSEL_CON(38),
3947 		SEL(7, 7), 0,
3948 		{ RK3588_CLK_200M_SRC , RK3588_CLK_100M_SRC },
3949 	},
3950 	{
3951 		RK3588_CLK_I2C3, RK3588_CRU_CLKSEL_CON(38),
3952 		SEL(8, 8), 0,
3953 		{ RK3588_CLK_200M_SRC , RK3588_CLK_100M_SRC },
3954 	},
3955 	{
3956 		RK3588_CLK_I2C4, RK3588_CRU_CLKSEL_CON(38),
3957 		SEL(9, 9), 0,
3958 		{ RK3588_CLK_200M_SRC , RK3588_CLK_100M_SRC },
3959 	},
3960 	{
3961 		RK3588_CLK_I2C5, RK3588_CRU_CLKSEL_CON(38),
3962 		SEL(10, 10), 0,
3963 		{ RK3588_CLK_200M_SRC , RK3588_CLK_100M_SRC },
3964 	},
3965 	{
3966 		RK3588_CLK_I2C6, RK3588_CRU_CLKSEL_CON(38),
3967 		SEL(11, 11), 0,
3968 		{ RK3588_CLK_200M_SRC , RK3588_CLK_100M_SRC },
3969 	},
3970 	{
3971 		RK3588_CLK_I2C7, RK3588_CRU_CLKSEL_CON(38),
3972 		SEL(12, 12), 0,
3973 		{ RK3588_CLK_200M_SRC , RK3588_CLK_100M_SRC },
3974 	},
3975 	{
3976 		RK3588_CLK_I2C8, RK3588_CRU_CLKSEL_CON(38),
3977 		SEL(13, 13), 0,
3978 		{ RK3588_CLK_200M_SRC , RK3588_CLK_100M_SRC },
3979 	},
3980 	{
3981 		RK3588_CLK_SPI0, RK3588_CRU_CLKSEL_CON(59),
3982 		SEL(3, 2), 0,
3983 		{ RK3588_CLK_200M_SRC, RK3588_CLK_150M_SRC, RK3588_XIN24M },
3984 	},
3985 	{
3986 		RK3588_CLK_SPI1, RK3588_CRU_CLKSEL_CON(59),
3987 		SEL(5, 4), 0,
3988 		{ RK3588_CLK_200M_SRC, RK3588_CLK_150M_SRC, RK3588_XIN24M },
3989 	},
3990 	{
3991 		RK3588_CLK_SPI2, RK3588_CRU_CLKSEL_CON(59),
3992 		SEL(7, 6), 0,
3993 		{ RK3588_CLK_200M_SRC, RK3588_CLK_150M_SRC, RK3588_XIN24M },
3994 	},
3995 	{
3996 		RK3588_CLK_SPI3, RK3588_CRU_CLKSEL_CON(59),
3997 		SEL(9, 8), 0,
3998 		{ RK3588_CLK_200M_SRC, RK3588_CLK_150M_SRC, RK3588_XIN24M },
3999 	},
4000 	{
4001 		RK3588_CLK_SPI4, RK3588_CRU_CLKSEL_CON(59),
4002 		SEL(11, 10), 0,
4003 		{ RK3588_CLK_200M_SRC, RK3588_CLK_150M_SRC, RK3588_XIN24M },
4004 	},
4005 	{
4006 		RK3588_CLK_TSADC, RK3588_CRU_CLKSEL_CON(41),
4007 		SEL(8, 8), DIV(7, 0),
4008 		{ RK3588_PLL_GPLL, RK3588_XIN24M },
4009 	},
4010 	{
4011 		RK3588_CLK_UART1_SRC, RK3588_CRU_CLKSEL_CON(41),
4012 		SEL(14, 14), DIV(13, 9),
4013 		{ RK3588_PLL_GPLL, RK3588_PLL_CPLL }
4014 	},
4015 	{
4016 		RK3588_CLK_UART1, RK3588_CRU_CLKSEL_CON(43),
4017 		SEL(1, 0), 0,
4018 		{ RK3588_CLK_UART1_SRC, RK3588_CLK_UART1_FRAC, RK3588_XIN24M }
4019 	},
4020 	{
4021 		RK3588_SCLK_UART1, 0, 0, 0,
4022 		{ RK3588_CLK_UART1 }
4023 	},
4024 	{
4025 		RK3588_CLK_UART2_SRC, RK3588_CRU_CLKSEL_CON(43),
4026 		SEL(7, 7), DIV(6, 2),
4027 		{ RK3588_PLL_GPLL, RK3588_PLL_CPLL }
4028 	},
4029 	{
4030 		RK3588_CLK_UART2, RK3588_CRU_CLKSEL_CON(45),
4031 		SEL(1, 0), 0,
4032 		{ RK3588_CLK_UART2_SRC, RK3588_CLK_UART2_FRAC, RK3588_XIN24M }
4033 	},
4034 	{
4035 		RK3588_SCLK_UART2, 0, 0, 0,
4036 		{ RK3588_CLK_UART2 }
4037 	},
4038 	{
4039 		RK3588_CLK_UART3_SRC, RK3588_CRU_CLKSEL_CON(45),
4040 		SEL(7, 7), DIV(6, 2),
4041 		{ RK3588_PLL_GPLL, RK3588_PLL_CPLL }
4042 	},
4043 	{
4044 		RK3588_CLK_UART3, RK3588_CRU_CLKSEL_CON(47),
4045 		SEL(1, 0), 0,
4046 		{ RK3588_CLK_UART3_SRC, RK3588_CLK_UART3_FRAC, RK3588_XIN24M }
4047 	},
4048 	{
4049 		RK3588_SCLK_UART3, 0, 0, 0,
4050 		{ RK3588_CLK_UART3 }
4051 	},
4052 	{
4053 		RK3588_CLK_UART4_SRC, RK3588_CRU_CLKSEL_CON(47),
4054 		SEL(7, 7), DIV(6, 2),
4055 		{ RK3588_PLL_GPLL, RK3588_PLL_CPLL }
4056 	},
4057 	{
4058 		RK3588_CLK_UART4, RK3588_CRU_CLKSEL_CON(49),
4059 		SEL(1, 0), 0,
4060 		{ RK3588_CLK_UART4_SRC, RK3588_CLK_UART4_FRAC, RK3588_XIN24M }
4061 	},
4062 	{
4063 		RK3588_SCLK_UART4, 0, 0, 0,
4064 		{ RK3588_CLK_UART4 }
4065 	},
4066 	{
4067 		RK3588_CLK_UART5_SRC, RK3588_CRU_CLKSEL_CON(49),
4068 		SEL(7, 7), DIV(6, 2),
4069 		{ RK3588_PLL_GPLL, RK3588_PLL_CPLL }
4070 	},
4071 	{
4072 		RK3588_CLK_UART5, RK3588_CRU_CLKSEL_CON(51),
4073 		SEL(1, 0), 0,
4074 		{ RK3588_CLK_UART5_SRC, RK3588_CLK_UART5_FRAC, RK3588_XIN24M }
4075 	},
4076 	{
4077 		RK3588_SCLK_UART5, 0, 0, 0,
4078 		{ RK3588_CLK_UART5 }
4079 	},
4080 	{
4081 		RK3588_CLK_UART6_SRC, RK3588_CRU_CLKSEL_CON(51),
4082 		SEL(7, 7), DIV(6, 2),
4083 		{ RK3588_PLL_GPLL, RK3588_PLL_CPLL }
4084 	},
4085 	{
4086 		RK3588_CLK_UART6, RK3588_CRU_CLKSEL_CON(53),
4087 		SEL(1, 0), 0,
4088 		{ RK3588_CLK_UART6_SRC, RK3588_CLK_UART6_FRAC, RK3588_XIN24M }
4089 	},
4090 	{
4091 		RK3588_SCLK_UART6, 0, 0, 0,
4092 		{ RK3588_CLK_UART6 }
4093 	},
4094 	{
4095 		RK3588_CLK_UART7_SRC, RK3588_CRU_CLKSEL_CON(53),
4096 		SEL(7, 7), DIV(6, 2),
4097 		{ RK3588_PLL_GPLL, RK3588_PLL_CPLL }
4098 	},
4099 	{
4100 		RK3588_CLK_UART7, RK3588_CRU_CLKSEL_CON(55),
4101 		SEL(1, 0), 0,
4102 		{ RK3588_CLK_UART7_SRC, RK3588_CLK_UART7_FRAC, RK3588_XIN24M }
4103 	},
4104 	{
4105 		RK3588_SCLK_UART7, 0, 0, 0,
4106 		{ RK3588_CLK_UART7 }
4107 	},
4108 	{
4109 		RK3588_CLK_UART8_SRC, RK3588_CRU_CLKSEL_CON(55),
4110 		SEL(7, 7), DIV(6, 2),
4111 		{ RK3588_PLL_GPLL, RK3588_PLL_CPLL }
4112 	},
4113 	{
4114 		RK3588_CLK_UART8, RK3588_CRU_CLKSEL_CON(57),
4115 		SEL(1, 0), 0,
4116 		{ RK3588_CLK_UART8_SRC, RK3588_CLK_UART8_FRAC, RK3588_XIN24M }
4117 	},
4118 	{
4119 		RK3588_SCLK_UART8, 0, 0, 0,
4120 		{ RK3588_CLK_UART8 }
4121 	},
4122 	{
4123 		RK3588_CLK_UART9_SRC, RK3588_CRU_CLKSEL_CON(57),
4124 		SEL(7, 7), DIV(6, 2),
4125 		{ RK3588_PLL_GPLL, RK3588_PLL_CPLL }
4126 	},
4127 	{
4128 		RK3588_CLK_UART9, RK3588_CRU_CLKSEL_CON(59),
4129 		SEL(1, 0), 0,
4130 		{ RK3588_CLK_UART9_SRC, RK3588_CLK_UART9_FRAC, RK3588_XIN24M }
4131 	},
4132 	{
4133 		RK3588_SCLK_UART9, 0, 0, 0,
4134 		{ RK3588_CLK_UART9 }
4135 	},
4136 	{
4137 		RK3588_ACLK_CENTER_ROOT, RK3588_CRU_CLKSEL_CON(165),
4138 		SEL(1, 0), 0,
4139 		{ RK3588_CLK_700M_SRC, RK3588_CLK_400M_SRC,
4140 		  RK3588_CLK_200M_SRC, RK3588_XIN24M }
4141 	},
4142 	{
4143 		RK3588_ACLK_CENTER_LOW_ROOT, RK3588_CRU_CLKSEL_CON(165),
4144 		SEL(3, 2), 0,
4145 		{ RK3588_CLK_500M_SRC, RK3588_CLK_250M_SRC,
4146 		  RK3588_CLK_100M_SRC, RK3588_XIN24M }
4147 	},
4148 	{
4149 		RK3588_HCLK_CENTER_ROOT, RK3588_CRU_CLKSEL_CON(165),
4150 		SEL(5, 4), 0,
4151 		{ RK3588_CLK_400M_SRC, RK3588_CLK_200M_SRC,
4152 		  RK3588_CLK_100M_SRC, RK3588_XIN24M }
4153 	},
4154 	{
4155 		RK3588_CLK_50M_SRC, RK3588_CRU_CLKSEL_CON(0),
4156 		SEL(5, 5), DIV(4, 0),
4157 		{ RK3588_PLL_GPLL, RK3588_PLL_CPLL }
4158 	},
4159 	{
4160 		RK3588_CLK_100M_SRC, RK3588_CRU_CLKSEL_CON(0),
4161 		SEL(11, 11), DIV(10, 6),
4162 		{ RK3588_PLL_GPLL, RK3588_PLL_CPLL }
4163 	},
4164 	{
4165 		RK3588_CLK_150M_SRC, RK3588_CRU_CLKSEL_CON(1),
4166 		SEL(5, 5), DIV(4, 0),
4167 		{ RK3588_PLL_GPLL, RK3588_PLL_CPLL }
4168 	},
4169 	{
4170 		RK3588_CLK_200M_SRC, RK3588_CRU_CLKSEL_CON(1),
4171 		SEL(11, 11), DIV(10, 6),
4172 		{ RK3588_PLL_GPLL, RK3588_PLL_CPLL }
4173 	},
4174 	{
4175 		RK3588_CLK_250M_SRC, RK3588_CRU_CLKSEL_CON(2),
4176 		SEL(5, 5), DIV(4, 0),
4177 		{ RK3588_PLL_GPLL, RK3588_PLL_CPLL }
4178 	},
4179 	{
4180 		RK3588_CLK_400M_SRC, RK3588_CRU_CLKSEL_CON(3),
4181 		SEL(11, 11), DIV(10, 6),
4182 		{ RK3588_PLL_GPLL, RK3588_PLL_CPLL }
4183 	},
4184 	{
4185 		RK3588_CLK_500M_SRC, RK3588_CRU_CLKSEL_CON(4),
4186 		SEL(11, 11), DIV(10, 6),
4187 		{ RK3588_PLL_GPLL, RK3588_PLL_CPLL }
4188 	},
4189 	{
4190 		RK3588_CLK_700M_SRC, RK3588_CRU_CLKSEL_CON(6),
4191 		SEL(5, 5), DIV(4, 0),
4192 		{ RK3588_PLL_GPLL, RK3588_PLL_SPLL }
4193 	},
4194 	{
4195 		RK3588_ACLK_TOP_ROOT, RK3588_CRU_CLKSEL_CON(8),
4196 		SEL(6, 5), 0,
4197 		{ RK3588_PLL_GPLL, RK3588_PLL_CPLL, RK3588_PLL_AUPLL }
4198 	},
4199 	{
4200 		RK3588_PCLK_TOP_ROOT, RK3588_CRU_CLKSEL_CON(8),
4201 		SEL(8, 7), 0,
4202 		{ RK3588_CLK_100M_SRC, RK3588_CLK_50M_SRC, RK3588_XIN24M }
4203 	},
4204 	{
4205 		RK3588_ACLK_LOW_TOP_ROOT, RK3588_CRU_CLKSEL_CON(8),
4206 		SEL(14, 14), DIV(13, 9),
4207 		{ RK3588_PLL_GPLL, RK3588_PLL_CPLL }
4208 	},
4209 	{
4210 		RK3588_CLK_GPU_SRC, RK3588_CRU_CLKSEL_CON(158),
4211 		SEL(7, 5), DIV(4, 0),
4212 		{ RK3588_PLL_GPLL, RK3588_PLL_CPLL, RK3588_PLL_AUPLL,
4213 		  RK3588_PLL_NPLL, RK3588_PLL_SPLL }
4214 	},
4215 	{
4216 		RK3588_CLK_GPU, 0, 0, 0,
4217 		{ RK3588_CLK_GPU_SRC },
4218 		SET_PARENT
4219 	},
4220 	{
4221 		RK3588_CCLK_EMMC, RK3588_CRU_CLKSEL_CON(77),
4222 		SEL(15, 14), DIV(13, 8),
4223 		{ RK3588_PLL_GPLL, RK3588_PLL_CPLL, RK3588_XIN24M }
4224 	},
4225 	{
4226 		RK3588_BCLK_EMMC, RK3588_CRU_CLKSEL_CON(78),
4227 		SEL(5, 5), DIV(4, 0),
4228 		{ RK3588_PLL_GPLL, RK3588_PLL_CPLL }
4229 	},
4230 	{
4231 		RK3588_TMCLK_EMMC, 0, 0, 0,
4232 		{ RK3588_XIN24M }
4233 	},
4234 	{
4235 		RK3588_CLK_GMAC_125M, RK3588_CRU_CLKSEL_CON(83),
4236 		SEL(15, 15), DIV(14, 8),
4237 		{ RK3588_PLL_GPLL, RK3588_PLL_CPLL }
4238 	},
4239 	{
4240 		RK3588_CCLK_SRC_SDIO, RK3588_CRU_CLKSEL_CON(172),
4241 		SEL(9, 8), DIV(7, 2),
4242 		{ RK3588_PLL_GPLL, RK3588_PLL_CPLL, RK3588_XIN24M }
4243 	},
4244 	{
4245 		RK3588_ACLK_VOP_ROOT, RK3588_CRU_CLKSEL_CON(110),
4246 		SEL(7, 5), DIV(4, 0),
4247 		{ RK3588_PLL_GPLL, RK3588_PLL_CPLL, RK3588_PLL_AUPLL,
4248 		  RK3588_PLL_NPLL, RK3588_PLL_SPLL }
4249 	},
4250 	{
4251 		RK3588_ACLK_VOP, 0, 0, 0,
4252 		{ RK3588_ACLK_VOP_SUB_SRC },
4253 		SET_PARENT
4254 	},
4255 	{
4256 		RK3588_ACLK_VOP_SUB_SRC, RK3588_CRU_CLKSEL_CON(115),
4257 		SEL(9, 9), 0,
4258 		{ RK3588_ACLK_VOP_ROOT, 0 /* RK3588_ACLK_VOP_DIV2_SRC */ },
4259 		SET_PARENT
4260 	},
4261 	{
4262 		RK3588_CLK_I2C0, RK3588_CRU_CLKSEL_CON(3),
4263 		SEL(6, 6), 0,
4264 		{ RK3588_CLK_PMU1_200M_SRC, RK3588_CLK_PMU1_100M_SRC },
4265 	},
4266 	{
4267 		RK3588_CLK_PMU1_50M_SRC, RK3588_PMUCRU_CLKSEL_CON(0),
4268 		0, DIV(3, 0),
4269 		{ RK3588_CLK_PMU1_400M_SRC }
4270 	},
4271 	{
4272 		RK3588_CLK_PMU1_100M_SRC, RK3588_PMUCRU_CLKSEL_CON(0),
4273 		0, DIV(6, 4),
4274 		{ RK3588_CLK_PMU1_400M_SRC }
4275 	},
4276 	{
4277 		RK3588_CLK_PMU1_200M_SRC, RK3588_PMUCRU_CLKSEL_CON(0),
4278 		0, DIV(9, 7),
4279 		{ RK3588_CLK_PMU1_400M_SRC }
4280 	},
4281 	{
4282 		RK3588_CLK_PMU1_400M_SRC, RK3588_PMUCRU_CLKSEL_CON(1),
4283 		SEL(5, 5), DIV(4, 0),
4284 		{ RK3588_CLK_400M_SRC, RK3588_XIN24M }
4285 	},
4286 	{
4287 		RK3588_PCLK_PMU1_ROOT, RK3588_PMUCRU_CLKSEL_CON(1),
4288 		SEL(9, 8), 0,
4289 		{ RK3588_CLK_PMU1_100M_SRC, RK3588_CLK_PMU1_50M_SRC,
4290 		  RK3588_XIN24M }
4291 	},
4292 	{
4293 		RK3588_PCLK_PMU0_ROOT, 0, 0, 0,
4294 		{ RK3588_PCLK_PMU1_ROOT },
4295 		SET_PARENT
4296 	},
4297 	{
4298 		RK3588_HCLK_PMU_CM0_ROOT, RK3588_PMUCRU_CLKSEL_CON(1),
4299 		SEL(11, 10), 0,
4300 		{ RK3588_CLK_PMU1_400M_SRC, RK3588_CLK_PMU1_200M_SRC,
4301 		  RK3588_CLK_PMU1_100M_SRC, RK3588_XIN24M }
4302 	},
4303 	{
4304 		RK3588_CLK_PMU1PWM, RK3588_PMUCRU_CLKSEL_CON(2),
4305 		SEL(10, 9), 0,
4306 		{ RK3588_CLK_PMU1_100M_SRC, RK3588_CLK_PMU1_50M_SRC,
4307 		  RK3588_XIN24M }
4308 	},
4309 	{
4310 		RK3588_CLK_UART0_SRC, RK3588_PMUCRU_CLKSEL_CON(3),
4311 		0, DIV(11, 7),
4312 		{ RK3588_PLL_CPLL }
4313 	},
4314 	{
4315 		RK3588_CLK_UART0, RK3588_PMUCRU_CLKSEL_CON(5),
4316 		SEL(1, 0), 0,
4317 		{ RK3588_CLK_UART0_SRC, RK3588_CLK_UART0_FRAC, RK3588_XIN24M }
4318 	},
4319 	{
4320 		RK3588_SCLK_UART0, 0, 0, 0,
4321 		{ RK3588_CLK_UART0 }
4322 	},
4323 	{
4324 		RK3588_CLK_REF_PIPE_PHY0_OSC_SRC, 0, 0, 0,
4325 		{ RK3588_XIN24M }
4326 	},
4327 	{
4328 		RK3588_CLK_REF_PIPE_PHY1_OSC_SRC, 0, 0, 0,
4329 		{ RK3588_XIN24M }
4330 	},
4331 	{
4332 		RK3588_CLK_REF_PIPE_PHY2_OSC_SRC, 0, 0, 0,
4333 		{ RK3588_XIN24M }
4334 	},
4335 	{
4336 		RK3588_CLK_REF_PIPE_PHY0_PLL_SRC, RK3588_CRU_CLKSEL_CON(176),
4337 		0, DIV(5, 0),
4338 		{ RK3588_PLL_PPLL }
4339 	},
4340 	{
4341 		RK3588_CLK_REF_PIPE_PHY1_PLL_SRC, RK3588_CRU_CLKSEL_CON(176),
4342 		0, DIV(11, 6),
4343 		{ RK3588_PLL_PPLL }
4344 	},
4345 	{
4346 		RK3588_CLK_REF_PIPE_PHY2_PLL_SRC, RK3588_CRU_CLKSEL_CON(177),
4347 		0, DIV(5, 0),
4348 		{ RK3588_PLL_PPLL }
4349 	},
4350 	{
4351 		RK3588_CLK_REF_PIPE_PHY0, RK3588_CRU_CLKSEL_CON(177),
4352 		SEL(6, 6), 0,
4353 		{ RK3588_CLK_REF_PIPE_PHY0_OSC_SRC,
4354 		  RK3588_CLK_REF_PIPE_PHY0_PLL_SRC },
4355 	},
4356 	{
4357 		RK3588_CLK_REF_PIPE_PHY1, RK3588_CRU_CLKSEL_CON(177),
4358 		SEL(7, 7), 0,
4359 		{ RK3588_CLK_REF_PIPE_PHY1_OSC_SRC,
4360 		  RK3588_CLK_REF_PIPE_PHY1_PLL_SRC },
4361 	},
4362 	{
4363 		RK3588_CLK_REF_PIPE_PHY2, RK3588_CRU_CLKSEL_CON(177),
4364 		SEL(8, 8), 0,
4365 		{ RK3588_CLK_REF_PIPE_PHY2_OSC_SRC,
4366 		  RK3588_CLK_REF_PIPE_PHY2_PLL_SRC },
4367 	},
4368 	{
4369 		/* Sentinel */
4370 	}
4371 };
4372 
4373 /* Certain test clocks are disabled. */
4374 const uint32_t rk3588_gates[78] = {
4375 	[2] = 0x00000050,
4376 	[22] = 0x00000200,
4377 	[25] = 0x00000200,
4378 	[29] = 0x00000004,
4379 	[66] = 0x00000004,
4380 };
4381 
4382 void
rk3588_init(struct rkclock_softc * sc)4383 rk3588_init(struct rkclock_softc *sc)
4384 {
4385 	int i;
4386 
4387 	/* The code below assumes all clocks are enabled.  Check this!. */
4388 	for (i = 0; i < nitems(rk3588_gates); i++) {
4389 		if (HREAD4(sc, RK3588_CRU_GATE_CON(i)) != rk3588_gates[i]) {
4390 			printf("CRU_GATE_CON%d: 0x%08x\n", i,
4391 			    HREAD4(sc, RK3588_CRU_GATE_CON(i)));
4392 		}
4393 	}
4394 
4395 	sc->sc_clocks = rk3588_clocks;
4396 }
4397 
4398 int
rk3588_set_pll(struct rkclock_softc * sc,bus_size_t base,uint32_t freq)4399 rk3588_set_pll(struct rkclock_softc *sc, bus_size_t base, uint32_t freq)
4400 {
4401 	uint32_t p, m, s, k;
4402 	int mode_shift = -1;
4403 
4404 	switch (base) {
4405 	case RK3588_CRU_AUPLL_CON(0):
4406 		mode_shift = 6;
4407 		break;
4408 	case RK3588_CRU_GPLL_CON(0):
4409 		mode_shift = 2;
4410 		break;
4411 	case RK3588_CRU_NPLL_CON(0):
4412 		mode_shift = 0;
4413 		break;
4414 	case RK3588_PHPTOPCRU_PPLL_CON(0):
4415 		mode_shift = 10;
4416 		break;
4417 	}
4418 	KASSERT(mode_shift != -1);
4419 
4420 	/*
4421 	 * It is not clear whether all combinations of the clock
4422 	 * dividers result in a stable clock.  Therefore this function
4423 	 * only supports a limited set of PLL clock rates.
4424 	 */
4425 	switch (freq) {
4426 	case 1188000000U:
4427 		p = 2; m = 198; s = 1; k = 0;
4428 		break;
4429 	case 1100000000U:
4430 		p = 3; m = 550; s = 2; k = 0;
4431 		break;
4432 	case 850000000U:
4433 		p = 3; m = 425; s = 2; k = 0;
4434 		break;
4435 	case 786432000U:
4436 		p = 2; m = 262; s = 2; k = 9437;
4437 		break;
4438 	case 100000000U:
4439 		p = 3; m = 400; s = 5; k = 0;
4440 		break;
4441 	default:
4442 		printf("%s: %u Hz\n", __func__, freq);
4443 		return -1;
4444 	}
4445 
4446 	/*
4447 	 * Select slow mode to guarantee a stable clock while we're
4448 	 * adjusting the PLL.
4449 	 */
4450 	HWRITE4(sc, RK3588_CRU_MODE_CON,
4451 	    (RK3588_CRU_MODE_MASK << 16 |RK3588_CRU_MODE_SLOW) << mode_shift);
4452 
4453 	/* Power down PLL. */
4454 	HWRITE4(sc, base + 0x0004,
4455 	    RK3588_CRU_PLL_RESETB << 16 | RK3588_CRU_PLL_RESETB);
4456 
4457 	/* Set PLL rate. */
4458 	HWRITE4(sc, base + 0x0000,
4459 	    RK3588_CRU_PLL_M_MASK << 16 | m << RK3588_CRU_PLL_M_SHIFT);
4460 	HWRITE4(sc, base + 0x0004,
4461 	    RK3588_CRU_PLL_S_MASK << 16 | s << RK3588_CRU_PLL_S_SHIFT |
4462 	    RK3588_CRU_PLL_P_MASK << 16 | p << RK3588_CRU_PLL_P_SHIFT);
4463 	HWRITE4(sc, base + 0x0008,
4464 	    RK3588_CRU_PLL_K_MASK << 16 | k << RK3588_CRU_PLL_K_SHIFT);
4465 
4466 	/* Power up PLL. */
4467 	HWRITE4(sc, base + 0x0004, RK3588_CRU_PLL_RESETB << 16);
4468 
4469 	/* Wait for PLL to stabilize. */
4470 	while ((HREAD4(sc, base + 0x0018) & RK3588_CRU_PLL_PLL_LOCK) == 0)
4471 		delay(10);
4472 
4473 	/* Switch back to normal mode. */
4474 	HWRITE4(sc, RK3588_CRU_MODE_CON,
4475 	    (RK3588_CRU_MODE_MASK << 16 | RK3588_CRU_MODE_NORMAL) << mode_shift);
4476 
4477 	return 0;
4478 }
4479 
4480 uint32_t
rk3588_get_pll(struct rkclock_softc * sc,bus_size_t base)4481 rk3588_get_pll(struct rkclock_softc *sc, bus_size_t base)
4482 {
4483 	uint64_t freq, frac;
4484 	uint32_t k, m, p, s;
4485 	uint32_t reg;
4486 
4487 	reg = HREAD4(sc, base);
4488 	m = (reg & RK3588_CRU_PLL_M_MASK) >> RK3588_CRU_PLL_M_SHIFT;
4489 	reg = HREAD4(sc, base + 4);
4490 	p = (reg & RK3588_CRU_PLL_P_MASK) >> RK3588_CRU_PLL_P_SHIFT;
4491 	s = (reg & RK3588_CRU_PLL_S_MASK) >> RK3588_CRU_PLL_S_SHIFT;
4492 	reg = HREAD4(sc, base + 8);
4493 	k = (reg & RK3588_CRU_PLL_K_MASK) >> RK3588_CRU_PLL_K_SHIFT;
4494 
4495 	freq = (24000000ULL * m) / p;
4496 	if (k) {
4497 		frac = ((24000000ULL * k) / (p * 65535));
4498 		freq += frac;
4499 	}
4500 
4501 	return freq >> s;
4502 }
4503 
4504 uint32_t
rk3588_get_frequency(void * cookie,uint32_t * cells)4505 rk3588_get_frequency(void *cookie, uint32_t *cells)
4506 {
4507 	struct rkclock_softc *sc = cookie;
4508 	uint32_t idx = cells[0];
4509 	uint32_t freq;
4510 
4511 	switch (idx) {
4512 	case RK3588_PLL_AUPLL:
4513 		return rk3588_get_pll(sc, RK3588_CRU_AUPLL_CON(0));
4514 	case RK3588_PLL_CPLL:
4515 		return rk3588_get_pll(sc, RK3588_CRU_CPLL_CON(0));
4516 	case RK3588_PLL_GPLL:
4517 		return rk3588_get_pll(sc, RK3588_CRU_GPLL_CON(0));
4518 	case RK3588_PLL_NPLL:
4519 		return rk3588_get_pll(sc, RK3588_CRU_NPLL_CON(0));
4520 	case RK3588_PLL_PPLL:
4521 		return rk3588_get_pll(sc, RK3588_PHPTOPCRU_PPLL_CON(0));
4522 	case RK3588_PLL_SPLL:
4523 		return rkclock_external_frequency("spll");
4524 	case RK3588_XIN24M:
4525 		return 24000000;
4526 	default:
4527 		break;
4528 	}
4529 
4530 	freq = rkclock_get_frequency(sc, idx);
4531 	return freq;
4532 }
4533 
4534 int
rk3588_set_frequency(void * cookie,uint32_t * cells,uint32_t freq)4535 rk3588_set_frequency(void *cookie, uint32_t *cells, uint32_t freq)
4536 {
4537 	struct rkclock_softc *sc = cookie;
4538 	uint32_t idx = cells[0];
4539 
4540 	switch (idx) {
4541 	case RK3588_PLL_AUPLL:
4542 		return rk3588_set_pll(sc, RK3588_CRU_AUPLL_CON(0), freq);
4543 	case RK3588_PLL_GPLL:
4544 		return rk3588_set_pll(sc, RK3588_CRU_GPLL_CON(0), freq);
4545 	case RK3588_PLL_NPLL:
4546 		return rk3588_set_pll(sc, RK3588_CRU_NPLL_CON(0), freq);
4547 	case RK3588_PLL_PPLL:
4548 		return rk3588_set_pll(sc, RK3588_PHPTOPCRU_PPLL_CON(0), freq);
4549 	default:
4550 		break;
4551 	}
4552 
4553 	return rkclock_set_frequency(sc, idx, freq);
4554 }
4555 
4556 void
rk3588_enable(void * cookie,uint32_t * cells,int on)4557 rk3588_enable(void *cookie, uint32_t *cells, int on)
4558 {
4559 	uint32_t idx = cells[0];
4560 
4561 	/* All clocks are enabled upon hardware reset. */
4562 	if (!on) {
4563 		printf("%s: 0x%08x\n", __func__, idx);
4564 		return;
4565 	}
4566 }
4567 
4568 void
rk3588_reset(void * cookie,uint32_t * cells,int on)4569 rk3588_reset(void *cookie, uint32_t *cells, int on)
4570 {
4571 	struct rkclock_softc *sc = cookie;
4572 	uint32_t idx = cells[0];
4573 	uint32_t bit, mask, reg;
4574 
4575 	switch (idx) {
4576 	case RK3588_SRST_P_TSADC:
4577 		reg = RK3588_CRU_SOFTRST_CON(12);
4578 		bit = 0;
4579 		break;
4580 	case RK3588_SRST_TSADC:
4581 		reg = RK3588_CRU_SOFTRST_CON(12);
4582 		bit = 1;
4583 		break;
4584 	case RK3588_SRST_H_EMMC:
4585 		reg = RK3588_CRU_SOFTRST_CON(31);
4586 		bit = 4;
4587 		break;
4588 	case RK3588_SRST_A_EMMC:
4589 		reg = RK3588_CRU_SOFTRST_CON(31);
4590 		bit = 5;
4591 		break;
4592 	case RK3588_SRST_C_EMMC:
4593 		reg = RK3588_CRU_SOFTRST_CON(31);
4594 		bit = 6;
4595 		break;
4596 	case RK3588_SRST_B_EMMC:
4597 		reg = RK3588_CRU_SOFTRST_CON(31);
4598 		bit = 7;
4599 		break;
4600 	case RK3588_SRST_T_EMMC:
4601 		reg = RK3588_CRU_SOFTRST_CON(31);
4602 		bit = 8;
4603 		break;
4604 	case RK3588_SRST_A_GMAC0:
4605 		reg = RK3588_CRU_SOFTRST_CON(32);
4606 		bit = 10;
4607 		break;
4608 	case RK3588_SRST_A_GMAC1:
4609 		reg = RK3588_CRU_SOFTRST_CON(32);
4610 		bit = 11;
4611 		break;
4612 	case RK3588_SRST_PCIE0_POWER_UP:
4613 		reg = RK3588_CRU_SOFTRST_CON(32);
4614 		bit = 13;
4615 		break;
4616 	case RK3588_SRST_PCIE1_POWER_UP:
4617 		reg = RK3588_CRU_SOFTRST_CON(32);
4618 		bit = 14;
4619 		break;
4620 	case RK3588_SRST_PCIE2_POWER_UP:
4621 		reg = RK3588_CRU_SOFTRST_CON(32);
4622 		bit = 15;
4623 		break;
4624 	case RK3588_SRST_PCIE3_POWER_UP:
4625 		reg = RK3588_CRU_SOFTRST_CON(33);
4626 		bit = 0;
4627 		break;
4628 	case RK3588_SRST_PCIE4_POWER_UP:
4629 		reg = RK3588_CRU_SOFTRST_CON(33);
4630 		bit = 1;
4631 		break;
4632 	case RK3588_SRST_P_PCIE0:
4633 		reg = RK3588_CRU_SOFTRST_CON(33);
4634 		bit = 12;
4635 		break;
4636 	case RK3588_SRST_P_PCIE1:
4637 		reg = RK3588_CRU_SOFTRST_CON(33);
4638 		bit = 13;
4639 		break;
4640 	case RK3588_SRST_P_PCIE2:
4641 		reg = RK3588_CRU_SOFTRST_CON(33);
4642 		bit = 14;
4643 		break;
4644 	case RK3588_SRST_P_PCIE3:
4645 		reg = RK3588_CRU_SOFTRST_CON(33);
4646 		bit = 15;
4647 		break;
4648 	case RK3588_SRST_P_PCIE4:
4649 		reg = RK3588_CRU_SOFTRST_CON(34);
4650 		bit = 0;
4651 		break;
4652 	case RK3588_SRST_A_USB3OTG2:
4653 		reg = RK3588_CRU_SOFTRST_CON(35);
4654 		bit = 7;
4655 		break;
4656 	case RK3588_SRST_A_USB3OTG0:
4657 		reg = RK3588_CRU_SOFTRST_CON(42);
4658 		bit = 4;
4659 		break;
4660 	case RK3588_SRST_A_USB3OTG1:
4661 		reg = RK3588_CRU_SOFTRST_CON(42);
4662 		bit = 7;
4663 		break;
4664 	case RK3588_SRST_REF_PIPE_PHY0:
4665 		reg = RK3588_CRU_SOFTRST_CON(77);
4666 		bit = 6;
4667 		break;
4668 	case RK3588_SRST_REF_PIPE_PHY1:
4669 		reg = RK3588_CRU_SOFTRST_CON(77);
4670 		bit = 7;
4671 		break;
4672 	case RK3588_SRST_REF_PIPE_PHY2:
4673 		reg = RK3588_CRU_SOFTRST_CON(77);
4674 		bit = 8;
4675 		break;
4676 	case RK3588_SRST_P_PCIE2_PHY0:
4677 		reg = RK3588_PHPTOPCRU_SOFTRST_CON(0);
4678 		bit = 5;
4679 		break;
4680 	case RK3588_SRST_P_PCIE2_PHY1:
4681 		reg = RK3588_PHPTOPCRU_SOFTRST_CON(0);
4682 		bit = 6;
4683 		break;
4684 	case RK3588_SRST_P_PCIE2_PHY2:
4685 		reg = RK3588_PHPTOPCRU_SOFTRST_CON(0);
4686 		bit = 7;
4687 		break;
4688 	case RK3588_SRST_PCIE30_PHY:
4689 		reg = RK3588_PHPTOPCRU_SOFTRST_CON(0);
4690 		bit = 10;
4691 		break;
4692 	default:
4693 		printf("%s: 0x%08x\n", __func__, idx);
4694 		return;
4695 	}
4696 
4697 	mask = (1 << bit);
4698 	HWRITE4(sc, reg, mask << 16 | (on ? mask : 0));
4699 }
4700