xref: /openbsd-src/sys/dev/fdt/rkclock.c (revision c90a81c56dcebd6a1b73fe4aff9b03385b8e63b3)
1 /*	$OpenBSD: rkclock.c,v 1.41 2019/01/01 17:12:58 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/fdt.h>
30 
31 /* RK3288 registers */
32 #define RK3288_CRU_APLL_CON(i)		(0x0000 + (i) * 4)
33 #define RK3288_CRU_CPLL_CON(i)		(0x0020 + (i) * 4)
34 #define RK3288_CRU_GPLL_CON(i)		(0x0030 + (i) * 4)
35 #define  RK3288_CRU_PLL_CLKR_MASK		(0x3f << 8)
36 #define  RK3288_CRU_PLL_CLKR_SHIFT		8
37 #define  RK3288_CRU_PLL_CLKOD_MASK		(0xf << 0)
38 #define  RK3288_CRU_PLL_CLKOD_SHIFT		0
39 #define  RK3288_CRU_PLL_CLKF_MASK		(0x1fff << 0)
40 #define  RK3288_CRU_PLL_CLKF_SHIFT		0
41 #define  RK3288_CRU_PLL_RESET			(1 << 5)
42 #define RK3288_CRU_MODE_CON		0x0050
43 #define  RK3288_CRU_MODE_PLL_WORK_MODE_MASK	0x3
44 #define  RK3288_CRU_MODE_PLL_WORK_MODE_SLOW	0x0
45 #define  RK3288_CRU_MODE_PLL_WORK_MODE_NORMAL	0x1
46 #define RK3288_CRU_CLKSEL_CON(i)	(0x0060 + (i) * 4)
47 #define RK3288_CRU_SOFTRST_CON(i)	(0x01b8 + (i) * 4)
48 
49 /* RK3328 registers */
50 #define RK3328_CRU_APLL_CON(i)		(0x0000 + (i) * 4)
51 #define RK3328_CRU_DPLL_CON(i)		(0x0020 + (i) * 4)
52 #define RK3328_CRU_CPLL_CON(i)		(0x0040 + (i) * 4)
53 #define RK3328_CRU_GPLL_CON(i)		(0x0060 + (i) * 4)
54 #define RK3328_CRU_NPLL_CON(i)		(0x00a0 + (i) * 4)
55 #define  RK3328_CRU_PLL_POSTDIV1_MASK		(0x7 << 12)
56 #define  RK3328_CRU_PLL_POSTDIV1_SHIFT		12
57 #define  RK3328_CRU_PLL_FBDIV_MASK		(0xfff << 0)
58 #define  RK3328_CRU_PLL_FBDIV_SHIFT		0
59 #define  RK3328_CRU_PLL_DSMPD			(1 << 12)
60 #define  RK3328_CRU_PLL_PLL_LOCK		(1 << 10)
61 #define  RK3328_CRU_PLL_POSTDIV2_MASK		(0x7 << 6)
62 #define  RK3328_CRU_PLL_POSTDIV2_SHIFT		6
63 #define  RK3328_CRU_PLL_REFDIV_MASK		(0x3f << 0)
64 #define  RK3328_CRU_PLL_REFDIV_SHIFT		0
65 #define  RK3328_CRU_PLL_FRACDIV_MASK		(0xffffff << 0)
66 #define  RK3328_CRU_PLL_FRACDIV_SHIFT		0
67 #define RK3328_CRU_CRU_MODE		0x0080
68 #define  RK3328_CRU_CRU_MODE_MASK		0x1
69 #define  RK3328_CRU_CRU_MODE_SLOW		0x0
70 #define  RK3328_CRU_CRU_MODE_NORMAL		0x1
71 #define RK3328_CRU_CLKSEL_CON(i)	(0x0100 + (i) * 4)
72 #define  RK3328_CRU_CORE_CLK_PLL_SEL_MASK	(0x3 << 6)
73 #define  RK3328_CRU_CORE_CLK_PLL_SEL_SHIFT	6
74 #define  RK3328_CRU_CLK_CORE_DIV_CON_MASK	(0x1f << 0)
75 #define  RK3328_CRU_CLK_CORE_DIV_CON_SHIFT	0
76 #define  RK3328_CRU_ACLK_CORE_DIV_CON_MASK	(0x7 << 4)
77 #define  RK3328_CRU_ACLK_CORE_DIV_CON_SHIFT	4
78 #define  RK3328_CRU_CLK_CORE_DBG_DIV_CON_MASK	(0xf << 0)
79 #define  RK3328_CRU_CLK_CORE_DBG_DIV_CON_SHIFT	0
80 #define  RK3328_CRU_VOP_DCLK_SRC_SEL_MASK	(0x1 << 1)
81 #define  RK3328_CRU_VOP_DCLK_SRC_SEL_SHIFT	1
82 #define RK3328_CRU_CLKGATE_CON(i)	(0x0200 + (i) * 4)
83 #define RK3328_CRU_SOFTRST_CON(i)	(0x0300 + (i) * 4)
84 
85 /* RK3399 registers */
86 #define RK3399_CRU_LPLL_CON(i)		(0x0000 + (i) * 4)
87 #define RK3399_CRU_BPLL_CON(i)		(0x0020 + (i) * 4)
88 #define RK3399_CRU_DPLL_CON(i)		(0x0020 + (i) * 4)
89 #define RK3399_CRU_CPLL_CON(i)		(0x0060 + (i) * 4)
90 #define RK3399_CRU_GPLL_CON(i)		(0x0080 + (i) * 4)
91 #define RK3399_CRU_NPLL_CON(i)		(0x00a0 + (i) * 4)
92 #define RK3399_CRU_VPLL_CON(i)		(0x00c0 + (i) * 4)
93 #define  RK3399_CRU_PLL_FBDIV_MASK		(0xfff << 0)
94 #define  RK3399_CRU_PLL_FBDIV_SHIFT		0
95 #define  RK3399_CRU_PLL_POSTDIV2_MASK		(0x7 << 12)
96 #define  RK3399_CRU_PLL_POSTDIV2_SHIFT		12
97 #define  RK3399_CRU_PLL_POSTDIV1_MASK		(0x7 << 8)
98 #define  RK3399_CRU_PLL_POSTDIV1_SHIFT		8
99 #define  RK3399_CRU_PLL_REFDIV_MASK		(0x3f << 0)
100 #define  RK3399_CRU_PLL_REFDIV_SHIFT		0
101 #define  RK3399_CRU_PLL_PLL_WORK_MODE_MASK	(0x3 << 8)
102 #define  RK3399_CRU_PLL_PLL_WORK_MODE_SLOW	(0x0 << 8)
103 #define  RK3399_CRU_PLL_PLL_WORK_MODE_NORMAL	(0x1 << 8)
104 #define  RK3399_CRU_PLL_PLL_WORK_MODE_DEEP_SLOW	(0x2 << 8)
105 #define  RK3399_CRU_PLL_PLL_LOCK		(1U << 31)
106 #define RK3399_CRU_CLKSEL_CON(i)	(0x0100 + (i) * 4)
107 #define  RK3399_CRU_ACLKM_CORE_DIV_CON_MASK	(0x1f << 8)
108 #define  RK3399_CRU_ACLKM_CORE_DIV_CON_SHIFT	8
109 #define  RK3399_CRU_CORE_PLL_SEL_MASK		(0x3 << 6)
110 #define  RK3399_CRU_CORE_PLL_SEL_APLL		(0x0 << 6)
111 #define  RK3399_CRU_CORE_PLL_SEL_BPLL		(0x1 << 6)
112 #define  RK3399_CRU_CORE_PLL_SEL_DPLL		(0x2 << 6)
113 #define  RK3399_CRU_CORE_PLL_SEL_GPLL		(0x3 << 6)
114 #define  RK3399_CRU_CORE_PLL_SEL_SHIFT		6
115 #define  RK3399_CRU_CLK_CORE_DIV_CON_MASK	(0x1f << 0)
116 #define  RK3399_CRU_CLK_CORE_DIV_CON_SHIFT	0
117 #define  RK3399_CRU_PCLK_DBG_DIV_CON_MASK	(0x1f << 8)
118 #define  RK3399_CRU_PCLK_DBG_DIV_CON_SHIFT	8
119 #define  RK3399_CRU_ATCLK_CORE_DIV_CON_MASK	(0x1f << 0)
120 #define  RK3399_CRU_ATCLK_CORE_DIV_CON_SHIFT	0
121 #define  RK3399_CRU_CLK_SD_PLL_SEL_MASK		(0x7 << 8)
122 #define  RK3399_CRU_CLK_SD_PLL_SEL_SHIFT	8
123 #define  RK3399_CRU_CLK_SD_DIV_CON_MASK		(0x7f << 0)
124 #define  RK3399_CRU_CLK_SD_DIV_CON_SHIFT	0
125 #define RK3399_CRU_CLKGATE_CON(i)	(0x0300 + (i) * 4)
126 #define RK3399_CRU_SOFTRST_CON(i)	(0x0400 + (i) * 4)
127 #define RK3399_CRU_SDMMC_CON(i)		(0x0580 + (i) * 4)
128 
129 #define RK3399_PMUCRU_PPLL_CON(i)	(0x0000 + (i) * 4)
130 #define RK3399_PMUCRU_CLKSEL_CON(i)	(0x0080 + (i) * 4)
131 
132 #include "rkclock_clocks.h"
133 
134 struct rkclock {
135 	uint16_t idx;
136 	uint16_t reg;
137 	uint16_t sel_mask;
138 	uint16_t div_mask;
139 	uint16_t parents[8];
140 	uint32_t flags;
141 };
142 
143 #define SEL(l, f)	(((1 << (l - f + 1)) - 1) << f)
144 #define DIV(l, f)	SEL(l, f)
145 
146 #define FIXED_PARENT	(1 << 0)
147 #define SET_PARENT	(1 << 1)
148 
149 #define HREAD4(sc, reg)							\
150 	(bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg)))
151 #define HWRITE4(sc, reg, val)						\
152 	bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
153 #define HSET4(sc, reg, bits)						\
154 	HWRITE4((sc), (reg), HREAD4((sc), (reg)) | (bits))
155 #define HCLR4(sc, reg, bits)						\
156 	HWRITE4((sc), (reg), HREAD4((sc), (reg)) & ~(bits))
157 
158 struct rkclock_softc {
159 	struct device		sc_dev;
160 	bus_space_tag_t		sc_iot;
161 	bus_space_handle_t	sc_ioh;
162 
163 	uint32_t		sc_phandle;
164 	struct rkclock		*sc_clocks;
165 
166 	struct clock_device	sc_cd;
167 	struct reset_device	sc_rd;
168 };
169 
170 int rkclock_match(struct device *, void *, void *);
171 void rkclock_attach(struct device *, struct device *, void *);
172 
173 struct cfattach	rkclock_ca = {
174 	sizeof (struct rkclock_softc), rkclock_match, rkclock_attach
175 };
176 
177 struct cfdriver rkclock_cd = {
178 	NULL, "rkclock", DV_DULL
179 };
180 
181 void	rk3288_init(struct rkclock_softc *);
182 uint32_t rk3288_get_frequency(void *, uint32_t *);
183 int	rk3288_set_frequency(void *, uint32_t *, uint32_t);
184 void	rk3288_enable(void *, uint32_t *, int);
185 void	rk3288_reset(void *, uint32_t *, int);
186 
187 void	rk3328_init(struct rkclock_softc *);
188 uint32_t rk3328_get_frequency(void *, uint32_t *);
189 int	rk3328_set_frequency(void *, uint32_t *, uint32_t);
190 int	rk3328_set_parent(void *, uint32_t *, uint32_t *);
191 void	rk3328_enable(void *, uint32_t *, int);
192 void	rk3328_reset(void *, uint32_t *, int);
193 
194 void	rk3399_init(struct rkclock_softc *);
195 uint32_t rk3399_get_frequency(void *, uint32_t *);
196 int	rk3399_set_frequency(void *, uint32_t *, uint32_t);
197 void	rk3399_enable(void *, uint32_t *, int);
198 void	rk3399_reset(void *, uint32_t *, int);
199 
200 void	rk3399_pmu_init(struct rkclock_softc *);
201 uint32_t rk3399_pmu_get_frequency(void *, uint32_t *);
202 int	rk3399_pmu_set_frequency(void *, uint32_t *, uint32_t);
203 void	rk3399_pmu_enable(void *, uint32_t *, int);
204 void	rk3399_pmu_reset(void *, uint32_t *, int);
205 
206 struct rkclock_compat {
207 	const char *compat;
208 	int	assign;
209 	void	(*init)(struct rkclock_softc *);
210 	void	(*enable)(void *, uint32_t *, int);
211 	uint32_t (*get_frequency)(void *, uint32_t *);
212 	int	(*set_frequency)(void *, uint32_t *, uint32_t);
213 	int	(*set_parent)(void *, uint32_t *, uint32_t *);
214 	void	(*reset)(void *, uint32_t *, int);
215 };
216 
217 struct rkclock_compat rkclock_compat[] = {
218 	{
219 		"rockchip,rk3288-cru", 0, rk3288_init,
220 		rk3288_enable, rk3288_get_frequency,
221 		rk3288_set_frequency, NULL,
222 		rk3288_reset
223 	},
224 	{
225 		"rockchip,rk3328-cru", 1, rk3328_init,
226 		rk3328_enable, rk3328_get_frequency,
227 		rk3328_set_frequency, rk3328_set_parent,
228 		rk3328_reset
229 	},
230 	{
231 		"rockchip,rk3399-cru", 1, rk3399_init,
232 		rk3399_enable, rk3399_get_frequency,
233 		rk3399_set_frequency, NULL,
234 		rk3399_reset
235 	},
236 	{
237 		"rockchip,rk3399-pmucru", 1, rk3399_pmu_init,
238 		rk3399_pmu_enable, rk3399_pmu_get_frequency,
239 		rk3399_pmu_set_frequency, NULL,
240 		rk3399_pmu_reset
241 	}
242 };
243 
244 int
245 rkclock_match(struct device *parent, void *match, void *aux)
246 {
247 	struct fdt_attach_args *faa = aux;
248 	int i;
249 
250 	for (i = 0; i < nitems(rkclock_compat); i++) {
251 		if (OF_is_compatible(faa->fa_node, rkclock_compat[i].compat))
252 			return 10;
253 	}
254 
255 	return 0;
256 }
257 
258 void
259 rkclock_attach(struct device *parent, struct device *self, void *aux)
260 {
261 	struct rkclock_softc *sc = (struct rkclock_softc *)self;
262 	struct fdt_attach_args *faa = aux;
263 	int i;
264 
265 	if (faa->fa_nreg < 1) {
266 		printf(": no registers\n");
267 		return;
268 	}
269 
270 	sc->sc_iot = faa->fa_iot;
271 	if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr,
272 	    faa->fa_reg[0].size, 0, &sc->sc_ioh)) {
273 		printf(": can't map registers\n");
274 		return;
275 	}
276 
277 	printf("\n");
278 
279 	sc->sc_phandle = OF_getpropint(faa->fa_node, "phandle", 0);
280 
281 	for (i = 0; i < nitems(rkclock_compat); i++) {
282 		if (OF_is_compatible(faa->fa_node, rkclock_compat[i].compat)) {
283 			break;
284 		}
285 	}
286 	KASSERT(i < nitems(rkclock_compat));
287 
288 	if (rkclock_compat[i].init)
289 		rkclock_compat[i].init(sc);
290 
291 	sc->sc_cd.cd_node = faa->fa_node;
292 	sc->sc_cd.cd_cookie = sc;
293 	sc->sc_cd.cd_enable = rkclock_compat[i].enable;
294 	sc->sc_cd.cd_get_frequency = rkclock_compat[i].get_frequency;
295 	sc->sc_cd.cd_set_frequency = rkclock_compat[i].set_frequency;
296 	sc->sc_cd.cd_set_parent = rkclock_compat[i].set_parent;
297 	clock_register(&sc->sc_cd);
298 
299 	sc->sc_rd.rd_node = faa->fa_node;
300 	sc->sc_rd.rd_cookie = sc;
301 	sc->sc_rd.rd_reset = rkclock_compat[i].reset;
302 	reset_register(&sc->sc_rd);
303 
304 	if (rkclock_compat[i].assign)
305 		clock_set_assigned(faa->fa_node);
306 }
307 
308 struct rkclock *
309 rkclock_lookup(struct rkclock_softc *sc, uint32_t idx)
310 {
311 	struct rkclock *clk;
312 
313 	for (clk = sc->sc_clocks; clk->idx; clk++) {
314 		if (clk->idx == idx)
315 			return clk;
316 	}
317 
318 	return NULL;
319 }
320 
321 uint32_t
322 rkclock_div_con(struct rkclock_softc *sc, struct rkclock *clk,
323     uint32_t mux, uint32_t freq)
324 {
325 	uint32_t parent_freq, div, div_con, max_div_con;
326 	uint32_t idx = clk->parents[mux];
327 
328 	/* Derive maximum value from mask. */
329 	max_div_con = clk->div_mask >> (ffs(clk->div_mask) - 1);
330 
331 	parent_freq = sc->sc_cd.cd_get_frequency(sc, &idx);
332 	div = (parent_freq + freq - 1) / freq;
333 	div_con = (div > 0 ? div - 1 : 0);
334 	return (div_con < max_div_con) ? div_con : max_div_con;
335 }
336 
337 uint32_t
338 rkclock_freq(struct rkclock_softc *sc, struct rkclock *clk,
339     uint32_t mux, uint32_t freq)
340 {
341 	uint32_t parent_freq, div_con;
342 	uint32_t idx = clk->parents[mux];
343 
344 	parent_freq = sc->sc_cd.cd_get_frequency(sc, &idx);
345 	div_con = rkclock_div_con(sc, clk, mux, freq);
346 	return parent_freq / (div_con + 1);
347 }
348 
349 uint32_t
350 rkclock_get_frequency(struct rkclock_softc *sc, uint32_t idx)
351 {
352 	struct rkclock *clk;
353 	uint32_t reg, mux, div_con;
354 	int shift;
355 
356 	clk = rkclock_lookup(sc, idx);
357 	if (clk == NULL) {
358 		printf("%s: 0x%08x\n", __func__, idx);
359 		return 0;
360 	}
361 
362 	reg = HREAD4(sc, clk->reg);
363 	shift = ffs(clk->sel_mask) - 1;
364 	if (shift == -1)
365 		mux = 0;
366 	else
367 		mux = (reg & clk->sel_mask) >> shift;
368 	shift = ffs(clk->div_mask) - 1;
369 	if (shift == -1)
370 		div_con = 0;
371 	else
372 		div_con = (reg & clk->div_mask) >> shift;
373 
374 	if (clk->parents[mux] == 0) {
375 		printf("%s: parent 0x%08x\n", __func__, idx);
376 		return 0;
377 	}
378 	idx = clk->parents[mux];
379 	return sc->sc_cd.cd_get_frequency(sc, &idx) / (div_con + 1);
380 }
381 
382 int
383 rkclock_set_frequency(struct rkclock_softc *sc, uint32_t idx, uint32_t freq)
384 {
385 	struct rkclock *clk;
386 	uint32_t reg, mux, div_con;
387 	uint32_t best_freq, best_mux, f;
388 	int sel_shift, div_shift, i;
389 
390 	clk = rkclock_lookup(sc, idx);
391 	if (clk == NULL || clk->div_mask == 0) {
392 		printf("%s: 0x%08x\n", __func__, idx);
393 		return -1;
394 	}
395 
396 	reg = HREAD4(sc, clk->reg);
397 	sel_shift = ffs(clk->sel_mask) - 1;
398 	if (sel_shift == -1)
399 		mux = sel_shift = 0;
400 	else
401 		mux = (reg & clk->sel_mask) >> sel_shift;
402 
403 	if (clk->parents[mux] == 0) {
404 		printf("%s: parent 0x%08x\n", __func__, idx);
405 		return 0;
406 	}
407 
408 	if (clk->flags & SET_PARENT) {
409 		idx = clk->parents[mux];
410 		sc->sc_cd.cd_set_frequency(sc, &idx, freq);
411 	}
412 
413 	/*
414 	 * Start out with the current parent.  This prevents
415 	 * unecessary switching to a different parent.
416 	 */
417 	best_freq = rkclock_freq(sc, clk, mux, freq);
418 	best_mux = mux;
419 
420 	/*
421 	 * Find the parent that allows configuration of a frequency
422 	 * closest to the target frequency.
423 	 */
424 	if ((clk->flags & FIXED_PARENT) == 0) {
425 		for (i = 0; i < nitems(clk->parents); i++) {
426 			if (clk->parents[i] == 0)
427 				continue;
428 			f = rkclock_freq(sc, clk, i, freq);
429 			if ((f > best_freq && f <= freq) ||
430 			    (f < best_freq && f >= freq)) {
431 				best_freq = f;
432 				best_mux = i;
433 			}
434 		}
435 	}
436 
437 	div_con = rkclock_div_con(sc, clk, best_mux, freq);
438 	div_shift = ffs(clk->div_mask) - 1;
439 	HWRITE4(sc, clk->reg,
440 	    clk->sel_mask << 16 | best_mux << sel_shift |
441 	    clk->div_mask << 16 | div_con << div_shift);
442 	return 0;
443 }
444 
445 int
446 rkclock_set_parent(struct rkclock_softc *sc, uint32_t idx, uint32_t parent)
447 {
448 	struct rkclock *clk;
449 	uint32_t mux;
450 	int shift;
451 
452 	clk = rkclock_lookup(sc, idx);
453 	if (clk == NULL || clk->sel_mask == 0) {
454 		printf("%s: 0x%08x\n", __func__, idx);
455 		return -1;
456 	}
457 
458 	for (mux = 0; mux < nitems(clk->parents); mux++) {
459 		if (clk->parents[mux] == parent)
460 			break;
461 	}
462 	if (mux == nitems(clk->parents) || parent == 0) {
463 		printf("%s: 0x%08x parent 0x%08x\n", __func__, idx, parent);
464 		return -1;
465 	}
466 
467 	shift = ffs(clk->sel_mask) - 1;
468 	HWRITE4(sc, clk->reg, clk->sel_mask << 16 | mux << shift);
469 	return 0;
470 }
471 
472 /*
473  * Rockchip RK3288
474  */
475 
476 void
477 rk3288_init(struct rkclock_softc *sc)
478 {
479 	int node;
480 
481 	/*
482 	 * Since the hardware comes up with a really conservative CPU
483 	 * clock frequency, and U-Boot doesn't set it to a more
484 	 * reasonable default, try to do so here.  These defaults were
485 	 * chosen assuming that the CPU voltage is at least 1.1 V.
486 	 * Only do this on the Tinker-RK3288 for now where this is
487 	 * likely to be true given the default voltages for the
488 	 * regulators on that board.
489 	 */
490 	node = OF_finddevice("/");
491 	if (OF_is_compatible(node, "rockchip,rk3288-tinker")) {
492 		uint32_t idx;
493 
494 		/* Run at 1.2 GHz. */
495 		idx = RK3288_ARMCLK;
496 		rk3288_set_frequency(sc, &idx, 1200000000);
497 	}
498 }
499 
500 uint32_t
501 rk3288_get_pll(struct rkclock_softc *sc, bus_size_t base)
502 {
503 	uint32_t clkod, clkr, clkf;
504 	uint32_t reg;
505 
506 	reg = HREAD4(sc, base);
507 	clkod = (reg & RK3288_CRU_PLL_CLKOD_MASK) >>
508 	    RK3288_CRU_PLL_CLKOD_SHIFT;
509 	clkr = (reg & RK3288_CRU_PLL_CLKR_MASK) >>
510 	    RK3288_CRU_PLL_CLKR_SHIFT;
511 	reg = HREAD4(sc, base + 4);
512 	clkf = (reg & RK3288_CRU_PLL_CLKF_MASK) >>
513 	    RK3288_CRU_PLL_CLKF_SHIFT;
514 	return 24000000ULL * (clkf + 1) / (clkr + 1) / (clkod + 1);
515 }
516 
517 int
518 rk3288_set_pll(struct rkclock_softc *sc, bus_size_t base, uint32_t freq)
519 {
520 	int shift = 4 * (base / RK3288_CRU_CPLL_CON(0));
521 	uint32_t no, nr, nf;
522 
523 	/*
524 	 * It is not clear whether all combinations of the clock
525 	 * dividers result in a stable clock.  Therefore this function
526 	 * only supports a limited set of PLL clock rates.  For now
527 	 * this set covers all the CPU frequencies supported by the
528 	 * Linux kernel.
529 	 */
530 	switch (freq) {
531 	case 1800000000:
532 	case 1704000000:
533 	case 1608000000:
534 	case 1512000000:
535 	case 1488000000:
536 	case 1416000000:
537 	case 1200000000:
538 		nr = no = 1;
539 		break;
540 	case 1008000000:
541 	case 816000000:
542 	case 696000000:
543 	case 600000000:
544 		nr = 1; no = 2;
545 		break;
546 	case 408000000:
547 	case 312000000:
548 		nr = 1; no = 4;
549 		break;
550 	case 216000000:
551 	case 126000000:
552 		nr = 1; no = 8;
553 		break;
554 	default:
555 		printf("%s: %u Hz\n", __func__, freq);
556 		return -1;
557 	}
558 
559 	/* Calculate feedback divider. */
560 	nf = freq * nr * no / 24000000;
561 
562 	/*
563 	 * Select slow mode to guarantee a stable clock while we're
564 	 * adjusting the PLL.
565 	 */
566 	HWRITE4(sc, RK3288_CRU_MODE_CON,
567 	    (RK3288_CRU_MODE_PLL_WORK_MODE_MASK << 16 |
568 	     RK3288_CRU_MODE_PLL_WORK_MODE_SLOW) << shift);
569 
570 	/* Assert reset. */
571 	HWRITE4(sc, base + 0x000c,
572 	    RK3288_CRU_PLL_RESET << 16 | RK3288_CRU_PLL_RESET);
573 
574 	/* Set PLL rate. */
575 	HWRITE4(sc, base + 0x0000,
576 	    RK3288_CRU_PLL_CLKR_MASK << 16 |
577 	    (nr - 1) << RK3288_CRU_PLL_CLKR_SHIFT |
578 	    RK3288_CRU_PLL_CLKOD_MASK << 16 |
579 	    (no - 1) << RK3288_CRU_PLL_CLKOD_SHIFT);
580 	HWRITE4(sc, base + 0x0004,
581 	    RK3288_CRU_PLL_CLKF_MASK << 16 |
582 	    (nf - 1) << RK3288_CRU_PLL_CLKF_SHIFT);
583 
584 	/* Deassert reset and wait. */
585 	HWRITE4(sc, base + 0x000c,
586 	    RK3288_CRU_PLL_RESET << 16);
587 	delay((nr * 500 / 24) + 1);
588 
589 	/* Switch back to normal mode. */
590 	HWRITE4(sc, RK3288_CRU_MODE_CON,
591 	    (RK3288_CRU_MODE_PLL_WORK_MODE_MASK << 16 |
592 	     RK3288_CRU_MODE_PLL_WORK_MODE_NORMAL) << shift);
593 
594 	return 0;
595 }
596 
597 uint32_t
598 rk3288_get_frequency(void *cookie, uint32_t *cells)
599 {
600 	struct rkclock_softc *sc = cookie;
601 	uint32_t idx = cells[0];
602 	uint32_t reg, mux, div_con, aclk_div_con;
603 
604 	switch (idx) {
605 	case RK3288_PLL_APLL:
606 		return rk3288_get_pll(sc, RK3288_CRU_APLL_CON(0));
607 	case RK3288_PLL_CPLL:
608 		return rk3288_get_pll(sc, RK3288_CRU_CPLL_CON(0));
609 	case RK3288_PLL_GPLL:
610 		return rk3288_get_pll(sc, RK3288_CRU_GPLL_CON(0));
611 	case RK3288_ARMCLK:
612 		reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(0));
613 		mux = (reg >> 15) & 0x1;
614 		div_con = (reg >> 8) & 0x1f;
615 		idx = (mux == 0) ? RK3288_PLL_APLL : RK3288_PLL_GPLL;
616 		return rk3288_get_frequency(sc, &idx) / (div_con + 1);
617 	case RK3288_CLK_SDMMC:
618 		reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(11));
619 		mux = (reg >> 6) & 0x3;
620 		div_con = reg & 0x3f;
621 		switch (mux) {
622 		case 0:
623 			idx = RK3288_PLL_CPLL;
624 			break;
625 		case 1:
626 			idx = RK3288_PLL_GPLL;
627 			break;
628 		case 2:
629 			return 24000000 / (div_con + 1);
630 		default:
631 			return 0;
632 		}
633 		return rk3288_get_frequency(sc, &idx) / (div_con + 1);
634 		break;
635 	case RK3288_CLK_UART0:
636 		reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(13));
637 		mux = (reg >> 8) & 0x3;
638 		div_con = reg & 0x7f;
639 		if (mux == 2)
640 			return 24000000 / (div_con + 1);
641 		break;
642 	case RK3288_CLK_UART1:
643 		reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(14));
644 		mux = (reg >> 8) & 0x3;
645 		div_con = reg & 0x7f;
646 		if (mux == 2)
647 			return 24000000 / (div_con + 1);
648 		break;
649 	case RK3288_CLK_UART2:
650 		reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(15));
651 		mux = (reg >> 8) & 0x3;
652 		div_con = reg & 0x7f;
653 		if (mux == 2)
654 			return 24000000 / (div_con + 1);
655 		break;
656 	case RK3288_CLK_UART3:
657 		reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(16));
658 		mux = (reg >> 8) & 0x3;
659 		div_con = reg & 0x7f;
660 		if (mux == 2)
661 			return 24000000 / (div_con + 1);
662 		break;
663 	case RK3288_CLK_UART4:
664 		reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(3));
665 		mux = (reg >> 8) & 0x3;
666 		div_con = reg & 0x7f;
667 		if (mux == 2)
668 			return 24000000 / (div_con + 1);
669 		break;
670 	case RK3288_PCLK_I2C0:
671 	case RK3288_PCLK_I2C2:
672 		reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(1));
673 		mux = (reg >> 15) & 0x1;
674 		/* pd_bus_pclk_div_con */
675 		div_con = (reg >> 12) & 0x7;
676 		if (mux == 1)
677 			idx = RK3288_PLL_GPLL;
678 		else
679 			idx = RK3288_PLL_CPLL;
680 		return rk3288_get_frequency(sc, &idx) / (div_con + 1);
681 	case RK3288_PCLK_I2C1:
682 	case RK3288_PCLK_I2C3:
683 	case RK3288_PCLK_I2C4:
684 	case RK3288_PCLK_I2C5:
685 		reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(10));
686 		mux = (reg >> 15) & 0x1;
687 		/* peri_pclk_div_con */
688 		div_con = (reg >> 12) & 0x3;
689 		/* peri_aclk_div_con */
690 		aclk_div_con = reg & 0xf;
691 		if (mux == 1)
692 			idx = RK3288_PLL_GPLL;
693 		else
694 			idx = RK3288_PLL_CPLL;
695 		return (rk3288_get_frequency(sc, &idx) / (aclk_div_con + 1)) >>
696 		    div_con;
697 	default:
698 		break;
699 	}
700 
701 	printf("%s: 0x%08x\n", __func__, idx);
702 	return 0;
703 }
704 
705 int
706 rk3288_set_frequency(void *cookie, uint32_t *cells, uint32_t freq)
707 {
708 	struct rkclock_softc *sc = cookie;
709 	uint32_t idx = cells[0];
710 	int error;
711 
712 	switch (idx) {
713 	case RK3288_PLL_APLL:
714 		return rk3288_set_pll(sc, RK3288_CRU_APLL_CON(0), freq);
715 	case RK3288_ARMCLK:
716 		idx = RK3288_PLL_APLL;
717 		error = rk3288_set_frequency(sc, &idx, freq);
718 		if (error == 0) {
719 			HWRITE4(sc, RK3288_CRU_CLKSEL_CON(0),
720 			    ((1 << 15) | (0x1f << 8)) << 16);
721 		}
722 		return error;
723 	}
724 
725 	printf("%s: 0x%08x\n", __func__, idx);
726 	return -1;
727 }
728 
729 void
730 rk3288_enable(void *cookie, uint32_t *cells, int on)
731 {
732 	uint32_t idx = cells[0];
733 
734 	switch (idx) {
735 	case RK3288_CLK_SDMMC:
736 	case RK3288_CLK_TSADC:
737 	case RK3288_CLK_UART0:
738 	case RK3288_CLK_UART1:
739 	case RK3288_CLK_UART2:
740 	case RK3288_CLK_UART3:
741 	case RK3288_CLK_UART4:
742 	case RK3288_CLK_MAC_RX:
743 	case RK3288_CLK_MAC_TX:
744 	case RK3288_CLK_SDMMC_DRV:
745 	case RK3288_CLK_SDMMC_SAMPLE:
746 	case RK3288_CLK_MAC:
747 	case RK3288_ACLK_GMAC:
748 	case RK3288_PCLK_GMAC:
749 	case RK3288_PCLK_I2C0:
750 	case RK3288_PCLK_I2C1:
751 	case RK3288_PCLK_I2C2:
752 	case RK3288_PCLK_I2C3:
753 	case RK3288_PCLK_I2C4:
754 	case RK3288_PCLK_I2C5:
755 	case RK3288_PCLK_TSADC:
756 	case RK3288_HCLK_HOST0:
757 	case RK3288_HCLK_SDMMC:
758 		/* Enabled by default. */
759 		break;
760 	default:
761 		printf("%s: 0x%08x\n", __func__, idx);
762 		break;
763 	}
764 }
765 
766 void
767 rk3288_reset(void *cookie, uint32_t *cells, int on)
768 {
769 	struct rkclock_softc *sc = cookie;
770 	uint32_t idx = cells[0];
771 	uint32_t mask = (1 << (idx % 16));
772 
773 	HWRITE4(sc, RK3288_CRU_SOFTRST_CON(idx / 16),
774 	    mask << 16 | (on ? mask : 0));
775 }
776 
777 /*
778  * Rockchip RK3328
779  */
780 
781 struct rkclock rk3328_clocks[] = {
782 	{
783 		RK3328_CLK_RTC32K, RK3328_CRU_CLKSEL_CON(38),
784 		SEL(15, 14), DIV(13, 0),
785 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_XIN24M }
786 	},
787 	{
788 		RK3328_CLK_SDMMC, RK3328_CRU_CLKSEL_CON(30),
789 		SEL(9, 8), DIV(7, 0),
790 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_XIN24M,
791 		  RK3328_USB480M }
792 	},
793 	{
794 		RK3328_CLK_SDIO, RK3328_CRU_CLKSEL_CON(31),
795 		SEL(9, 8), DIV(7, 0),
796 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_XIN24M,
797 		  RK3328_USB480M }
798 	},
799 	{
800 		RK3328_CLK_EMMC, RK3328_CRU_CLKSEL_CON(32),
801 		SEL(9, 8), DIV(7, 0),
802 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_XIN24M,
803 		  RK3328_USB480M }
804 	},
805 	{
806 		RK3328_CLK_TSADC, RK3328_CRU_CLKSEL_CON(22),
807 		0, DIV(9, 0),
808 		{ RK3328_CLK_24M }
809 	},
810 	{
811 		RK3328_CLK_UART0, RK3328_CRU_CLKSEL_CON(14),
812 		SEL(9, 8), 0,
813 		{ 0, 0, RK3328_XIN24M, RK3328_XIN24M }
814 	},
815 	{
816 		RK3328_CLK_UART1, RK3328_CRU_CLKSEL_CON(16),
817 		SEL(9, 8), 0,
818 		{ 0, 0, RK3328_XIN24M, RK3328_XIN24M }
819 	},
820 	{
821 		RK3328_CLK_UART2, RK3328_CRU_CLKSEL_CON(18),
822 		SEL(9, 8), 0,
823 		{ 0, 0, RK3328_XIN24M, RK3328_XIN24M }
824 	},
825 	{
826 		RK3328_CLK_WIFI, RK3328_CRU_CLKSEL_CON(52),
827 		SEL(7, 6), DIV(5, 0),
828 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_USB480M }
829 	},
830 	{
831 		RK3328_CLK_I2C0, RK3328_CRU_CLKSEL_CON(34),
832 		SEL(7, 7), DIV(6, 0),
833 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL }
834 	},
835 	{
836 		RK3328_CLK_I2C1, RK3328_CRU_CLKSEL_CON(34),
837 		SEL(15, 15), DIV(14, 8),
838 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL }
839 	},
840 	{
841 		RK3328_CLK_I2C2, RK3328_CRU_CLKSEL_CON(35),
842 		SEL(7, 7), DIV(6, 0),
843 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL }
844 	},
845 	{
846 		RK3328_CLK_I2C3, RK3328_CRU_CLKSEL_CON(35),
847 		SEL(15, 15), DIV(14, 8),
848 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL }
849 	},
850 	{
851 		RK3328_CLK_PDM, RK3328_CRU_CLKSEL_CON(20),
852 		SEL(15, 14), DIV(12, 8),
853 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_PLL_APLL },
854 		FIXED_PARENT | SET_PARENT
855 	},
856 	{
857 		RK3328_CLK_VDEC_CABAC, RK3328_CRU_CLKSEL_CON(48),
858 		SEL(15, 14), DIV(12, 8),
859 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY,
860 		  RK3328_USB480M }
861 	},
862 	{
863 		RK3328_CLK_VDEC_CORE, RK3328_CRU_CLKSEL_CON(49),
864 		SEL(7, 6), DIV(4, 0),
865 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY,
866 		  RK3328_USB480M }
867 	},
868 	{
869 		RK3328_CLK_VENC_DSP, RK3328_CRU_CLKSEL_CON(52),
870 		SEL(15, 14), DIV(12, 8),
871 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY,
872 		  RK3328_USB480M }
873 	},
874 	{
875 		RK3328_CLK_VENC_CORE, RK3328_CRU_CLKSEL_CON(51),
876 		SEL(15, 14), DIV(12, 8),
877 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY,
878 		  RK3328_USB480M }
879 	},
880 	{
881 		RK3328_CLK_TSP, RK3328_CRU_CLKSEL_CON(21),
882 		SEL(15, 15), DIV(12, 8),
883 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL }
884 	},
885 	{
886 		RK3328_DCLK_LCDC, RK3328_CRU_CLKSEL_CON(40),
887 		SEL(1, 1), 0,
888 		{ RK3328_HDMIPHY, RK3328_DCLK_LCDC_SRC }
889 	},
890 	{
891 		RK3328_ACLK_VOP_PRE, RK3328_CRU_CLKSEL_CON(39),
892 		SEL(7, 6), DIV(4, 0),
893 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY,
894 		  RK3328_USB480M }
895 	},
896 	{
897 		RK3328_ACLK_RGA_PRE, RK3328_CRU_CLKSEL_CON(36),
898 		SEL(15, 14), DIV(12, 8),
899 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY,
900 		  RK3328_USB480M }
901 	},
902 	{
903 		RK3328_ACLK_BUS_PRE, RK3328_CRU_CLKSEL_CON(0),
904 		SEL(14, 13), DIV(12, 8),
905 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY }
906 	},
907 	{
908 		RK3328_ACLK_PERI_PRE, RK3328_CRU_CLKSEL_CON(28),
909 		SEL(7, 6), DIV(4, 0),
910 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY }
911 	},
912 	{
913 		RK3328_ACLK_RKVDEC_PRE, RK3328_CRU_CLKSEL_CON(48),
914 		SEL(7, 6), DIV(4, 0),
915 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY,
916 		  RK3328_USB480M }
917 	},
918 	{
919 		RK3328_ACLK_RKVENC, RK3328_CRU_CLKSEL_CON(51),
920 		SEL(7, 6), DIV(4, 0),
921 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY,
922 		  RK3328_USB480M }
923 	},
924 	{
925 		RK3328_ACLK_VPU_PRE, RK3328_CRU_CLKSEL_CON(50),
926 		SEL(7, 6), DIV(4, 0),
927 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY,
928 		  RK3328_USB480M }
929 	},
930 	{
931 		RK3328_ACLK_VIO_PRE, RK3328_CRU_CLKSEL_CON(37),
932 		SEL(7, 6), DIV(4, 0),
933 		{ RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY,
934 		  RK3328_USB480M }
935 	},
936 	{
937 		RK3328_PCLK_BUS_PRE, RK3328_CRU_CLKSEL_CON(1),
938 		0, DIV(14, 12),
939 		{ RK3328_ACLK_BUS_PRE }
940 	},
941 	{
942 		RK3328_HCLK_BUS_PRE, RK3328_CRU_CLKSEL_CON(1),
943 		0, DIV(9, 8),
944 		{ RK3328_ACLK_BUS_PRE }
945 	},
946 	{
947 		RK3328_PCLK_PERI, RK3328_CRU_CLKSEL_CON(29),
948 		0, DIV(6, 4),
949 		{ RK3328_ACLK_PERI_PRE }
950 	},
951 	{
952 		RK3328_HCLK_PERI, RK3328_CRU_CLKSEL_CON(29),
953 		0, DIV(1, 0),
954 		{ RK3328_ACLK_PERI_PRE }
955 	},
956 	{
957 		RK3328_CLK_24M, RK3328_CRU_CLKSEL_CON(2),
958 		0, DIV(12, 8),
959 		{ RK3328_XIN24M }
960 	},
961 	{
962 		/* Sentinel */
963 	}
964 };
965 
966 void
967 rk3328_init(struct rkclock_softc *sc)
968 {
969 	int i;
970 
971 	/* The code below assumes all clocks are enabled.  Check this!. */
972 	for (i = 0; i <= 28; i++) {
973 		if (HREAD4(sc, RK3328_CRU_CLKGATE_CON(i)) != 0x00000000) {
974 			printf("CRU_CLKGATE_CON%d: 0x%08x\n", i,
975 			    HREAD4(sc, RK3328_CRU_CLKGATE_CON(i)));
976 		}
977 	}
978 
979 	sc->sc_clocks = rk3328_clocks;
980 }
981 
982 uint32_t
983 rk3328_armclk_parent(uint32_t mux)
984 {
985 	switch (mux) {
986 	case 0:
987 		return RK3328_PLL_APLL;
988 	case 1:
989 		return RK3328_PLL_GPLL;
990 	case 2:
991 		return RK3328_PLL_DPLL;
992 	case 3:
993 		return RK3328_PLL_NPLL;
994 	}
995 
996 	return 0;
997 }
998 
999 uint32_t
1000 rk3328_get_armclk(struct rkclock_softc *sc)
1001 {
1002 	uint32_t reg, mux, div_con;
1003 	uint32_t idx;
1004 
1005 	reg = HREAD4(sc, RK3328_CRU_CLKSEL_CON(0));
1006 	mux = (reg & RK3328_CRU_CORE_CLK_PLL_SEL_MASK) >>
1007 	    RK3328_CRU_CORE_CLK_PLL_SEL_SHIFT;
1008 	div_con = (reg & RK3328_CRU_CLK_CORE_DIV_CON_MASK) >>
1009 	    RK3328_CRU_CLK_CORE_DIV_CON_SHIFT;
1010 	idx = rk3328_armclk_parent(mux);
1011 
1012 	return rk3328_get_frequency(sc, &idx) / (div_con + 1);
1013 }
1014 
1015 int
1016 rk3328_set_armclk(struct rkclock_softc *sc, uint32_t freq)
1017 {
1018 	uint32_t reg, mux;
1019 	uint32_t old_freq, div;
1020 	uint32_t idx;
1021 
1022 	old_freq = rk3328_get_armclk(sc);
1023 	if (freq == old_freq)
1024 		return 0;
1025 
1026 	reg = HREAD4(sc, RK3328_CRU_CLKSEL_CON(0));
1027 	mux = (reg & RK3328_CRU_CORE_CLK_PLL_SEL_MASK) >>
1028 	    RK3328_CRU_CORE_CLK_PLL_SEL_SHIFT;
1029 
1030 	/* Keep the pclk_dbg clock at or below 300 MHz. */
1031 	div = 1;
1032 	while (freq / (div + 1) > 300000000)
1033 		div++;
1034 	/* and make sure we use an odd divider. */
1035 	if ((div % 2) == 0)
1036 		div++;
1037 
1038 	/* When ramping up, set clock dividers first. */
1039 	if (freq > old_freq) {
1040 		HWRITE4(sc, RK3328_CRU_CLKSEL_CON(0),
1041 		    RK3328_CRU_CLK_CORE_DIV_CON_MASK << 16 |
1042 		    0 << RK3328_CRU_CLK_CORE_DIV_CON_SHIFT);
1043 		HWRITE4(sc, RK3328_CRU_CLKSEL_CON(1),
1044 		    RK3328_CRU_ACLK_CORE_DIV_CON_MASK << 16 |
1045 		    1 << RK3328_CRU_ACLK_CORE_DIV_CON_SHIFT |
1046 		    RK3328_CRU_CLK_CORE_DBG_DIV_CON_MASK << 16 |
1047 		    div << RK3328_CRU_CLK_CORE_DBG_DIV_CON_SHIFT);
1048 	}
1049 
1050 	/* We always use NPLL and force the switch below if needed. */
1051 	idx = RK3328_PLL_NPLL;
1052 	rk3328_set_frequency(sc, &idx, freq);
1053 
1054 	/* When ramping down, set clock dividers last. */
1055 	if (freq < old_freq || mux != 3) {
1056 		HWRITE4(sc, RK3328_CRU_CLKSEL_CON(0),
1057 		    RK3328_CRU_CORE_CLK_PLL_SEL_MASK << 16 |
1058 		    3 << RK3328_CRU_CORE_CLK_PLL_SEL_SHIFT |
1059 		    RK3328_CRU_CLK_CORE_DIV_CON_MASK << 16 |
1060 		    0 << RK3328_CRU_CLK_CORE_DIV_CON_SHIFT);
1061 		HWRITE4(sc, RK3328_CRU_CLKSEL_CON(1),
1062 		    RK3328_CRU_ACLK_CORE_DIV_CON_MASK << 16 |
1063 		    1 << RK3328_CRU_ACLK_CORE_DIV_CON_SHIFT |
1064 		    RK3328_CRU_CLK_CORE_DBG_DIV_CON_MASK << 16 |
1065 		    div << RK3328_CRU_CLK_CORE_DBG_DIV_CON_SHIFT);
1066 	}
1067 
1068 	return 0;
1069 }
1070 
1071 uint32_t
1072 rk3328_get_pll(struct rkclock_softc *sc, bus_size_t base)
1073 {
1074 	uint32_t fbdiv, postdiv1, postdiv2, refdiv;
1075 	uint32_t dsmpd, fracdiv;
1076 	uint64_t frac = 0;
1077 	uint32_t reg;
1078 
1079 	reg = HREAD4(sc, base + 0x0000);
1080 	postdiv1 = (reg & RK3328_CRU_PLL_POSTDIV1_MASK) >>
1081 	    RK3328_CRU_PLL_POSTDIV1_SHIFT;
1082 	fbdiv = (reg & RK3328_CRU_PLL_FBDIV_MASK) >>
1083 	    RK3328_CRU_PLL_FBDIV_SHIFT;
1084 	reg = HREAD4(sc, base + 0x0004);
1085 	dsmpd = (reg & RK3328_CRU_PLL_DSMPD);
1086 	postdiv2 = (reg & RK3328_CRU_PLL_POSTDIV2_MASK) >>
1087 	    RK3328_CRU_PLL_POSTDIV2_SHIFT;
1088 	refdiv = (reg & RK3328_CRU_PLL_REFDIV_MASK) >>
1089 	    RK3328_CRU_PLL_REFDIV_SHIFT;
1090 	reg = HREAD4(sc, base + 0x0008);
1091 	fracdiv = (reg & RK3328_CRU_PLL_FRACDIV_MASK) >>
1092 	    RK3328_CRU_PLL_FRACDIV_SHIFT;
1093 
1094 	if (dsmpd == 0)
1095 		frac = (24000000ULL * fracdiv / refdiv) >> 24;
1096 	return ((24000000ULL * fbdiv / refdiv) + frac) / postdiv1 / postdiv2;
1097 }
1098 
1099 int
1100 rk3328_set_pll(struct rkclock_softc *sc, bus_size_t base, uint32_t freq)
1101 {
1102 	uint32_t fbdiv, postdiv1, postdiv2, refdiv;
1103 	int mode_shift = -1;
1104 
1105 	switch (base) {
1106 	case RK3328_CRU_APLL_CON(0):
1107 		mode_shift = 0;
1108 		break;
1109 	case RK3328_CRU_DPLL_CON(0):
1110 		mode_shift = 4;
1111 		break;
1112 	case RK3328_CRU_CPLL_CON(0):
1113 		mode_shift = 8;
1114 		break;
1115 	case RK3328_CRU_GPLL_CON(0):
1116 		mode_shift = 12;
1117 		break;
1118 	case RK3328_CRU_NPLL_CON(0):
1119 		mode_shift = 1;
1120 		break;
1121 	}
1122 	KASSERT(mode_shift != -1);
1123 
1124 	/*
1125 	 * It is not clear whether all combinations of the clock
1126 	 * dividers result in a stable clock.  Therefore this function
1127 	 * only supports a limited set of PLL clock rates.  For now
1128 	 * this set covers all the CPU frequencies supported by the
1129 	 * Linux kernel.
1130 	 */
1131 	switch (freq) {
1132 	case 1800000000U:
1133 	case 1704000000U:
1134 	case 1608000000U:
1135 	case 1512000000U:
1136 	case 1488000000U:
1137 	case 1416000000U:
1138 	case 1392000000U:
1139 	case 1296000000U:
1140 	case 1200000000U:
1141 	case 1104000000U:
1142 		postdiv1 = postdiv2 = refdiv = 1;
1143 		break;
1144 	case 1008000000U:
1145 	case 912000000U:
1146 	case 816000000U:
1147 	case 696000000U:
1148 		postdiv1 = 2; postdiv2 = refdiv = 1;
1149 		break;
1150 	case 600000000U:
1151 		postdiv1 = 3; postdiv2 = refdiv = 1;
1152 		break;
1153 	case 408000000U:
1154 	case 312000000U:
1155 		postdiv1 = postdiv2 = 2; refdiv = 1;
1156 		break;
1157 	case 216000000U:
1158 		postdiv1 = 4; postdiv2 = 2; refdiv = 1;
1159 		break;
1160 	case 96000000U:
1161 		postdiv1 = postdiv2 = 4; refdiv = 1;
1162 		break;
1163 	default:
1164 		printf("%s: %u Hz\n", __func__, freq);
1165 		return -1;
1166 	}
1167 
1168 	/* Calculate feedback divider. */
1169 	fbdiv = freq * postdiv1 * postdiv2 * refdiv / 24000000;
1170 
1171 	/*
1172 	 * Select slow mode to guarantee a stable clock while we're
1173 	 * adjusting the PLL.
1174 	 */
1175 	HWRITE4(sc, RK3328_CRU_CRU_MODE,
1176 	   (RK3328_CRU_CRU_MODE_MASK << 16 |
1177 	   RK3328_CRU_CRU_MODE_SLOW) << mode_shift);
1178 
1179 	/* Set PLL rate. */
1180 	HWRITE4(sc, base + 0x0000,
1181 	    RK3328_CRU_PLL_POSTDIV1_MASK << 16 |
1182 	    postdiv1 << RK3328_CRU_PLL_POSTDIV1_SHIFT |
1183 	    RK3328_CRU_PLL_FBDIV_MASK << 16 |
1184 	    fbdiv << RK3328_CRU_PLL_FBDIV_SHIFT);
1185 	HWRITE4(sc, base + 0x0004,
1186 	    RK3328_CRU_PLL_DSMPD << 16 | RK3328_CRU_PLL_DSMPD |
1187 	    RK3328_CRU_PLL_POSTDIV2_MASK << 16 |
1188 	    postdiv2 << RK3328_CRU_PLL_POSTDIV2_SHIFT |
1189 	    RK3328_CRU_PLL_REFDIV_MASK << 16 |
1190 	    refdiv << RK3328_CRU_PLL_REFDIV_SHIFT);
1191 
1192 	/* Wait for PLL to stabilize. */
1193 	while ((HREAD4(sc, base + 0x0004) & RK3328_CRU_PLL_PLL_LOCK) == 0)
1194 		delay(10);
1195 
1196 	/* Switch back to normal mode. */
1197 	HWRITE4(sc, RK3328_CRU_CRU_MODE,
1198 	   (RK3328_CRU_CRU_MODE_MASK << 16 |
1199 	   RK3328_CRU_CRU_MODE_NORMAL) << mode_shift);
1200 
1201 	return 0;
1202 }
1203 
1204 int
1205 rk3328_set_frac_pll(struct rkclock_softc *sc, bus_size_t base, uint32_t freq)
1206 {
1207 	uint32_t fbdiv, postdiv1, postdiv2, refdiv, fracdiv;
1208 	int mode_shift = -1;
1209 	uint32_t reg;
1210 
1211 	switch (base) {
1212 	case RK3328_CRU_APLL_CON(0):
1213 		mode_shift = 0;
1214 		break;
1215 	case RK3328_CRU_DPLL_CON(0):
1216 		mode_shift = 4;
1217 		break;
1218 	case RK3328_CRU_CPLL_CON(0):
1219 		mode_shift = 8;
1220 		break;
1221 	case RK3328_CRU_GPLL_CON(0):
1222 		mode_shift = 12;
1223 		break;
1224 	case RK3328_CRU_NPLL_CON(0):
1225 		mode_shift = 1;
1226 		break;
1227 	}
1228 	KASSERT(mode_shift != -1);
1229 
1230 	/*
1231 	 * It is not clear whether all combinations of the clock
1232 	 * dividers result in a stable clock.  Therefore this function
1233 	 * only supports a limited set of PLL clock rates.  This set
1234 	 * set covers all the fractional PLL frequencies supported by
1235 	 * the Linux kernel.
1236 	 */
1237 	switch (freq) {
1238 	case 1016064000U:
1239 		postdiv1 = postdiv2 = 1; refdiv = 3; fracdiv = 134217;
1240 		break;
1241 	case 983040000U:
1242 		postdiv1 = postdiv2 = 1; refdiv = 24; fracdiv = 671088;
1243 		break;
1244 	case 491520000U:
1245 		postdiv1 = 2; postdiv2 = 1; refdiv = 24; fracdiv = 671088;
1246 		break;
1247 	case 61440000U:
1248 		postdiv1 = 7; postdiv2 = 2; refdiv = 6; fracdiv = 671088;
1249 		break;
1250 	case 56448000U:
1251 		postdiv1 = postdiv2 = 4; refdiv = 12; fracdiv = 9797894;
1252 		break;
1253 	case 40960000U:
1254 		postdiv1 = 4; postdiv2 = 5; refdiv = 12; fracdiv = 10066239;
1255 		break;
1256 	default:
1257 		printf("%s: %u Hz\n", __func__, freq);
1258 		return -1;
1259 	}
1260 
1261 	/* Calculate feedback divider. */
1262 	fbdiv = (uint64_t)freq * postdiv1 * postdiv2 * refdiv / 24000000;
1263 
1264 	/*
1265 	 * Select slow mode to guarantee a stable clock while we're
1266 	 * adjusting the PLL.
1267 	 */
1268 	HWRITE4(sc, RK3328_CRU_CRU_MODE,
1269 	   (RK3328_CRU_CRU_MODE_MASK << 16 |
1270 	   RK3328_CRU_CRU_MODE_SLOW) << mode_shift);
1271 
1272 	/* Set PLL rate. */
1273 	HWRITE4(sc, base + 0x0000,
1274 	    RK3328_CRU_PLL_POSTDIV1_MASK << 16 |
1275 	    postdiv1 << RK3328_CRU_PLL_POSTDIV1_SHIFT |
1276 	    RK3328_CRU_PLL_FBDIV_MASK << 16 |
1277 	    fbdiv << RK3328_CRU_PLL_FBDIV_SHIFT);
1278 	HWRITE4(sc, base + 0x0004,
1279 	    RK3328_CRU_PLL_DSMPD << 16 |
1280 	    RK3328_CRU_PLL_POSTDIV2_MASK << 16 |
1281 	    postdiv2 << RK3328_CRU_PLL_POSTDIV2_SHIFT |
1282 	    RK3328_CRU_PLL_REFDIV_MASK << 16 |
1283 	    refdiv << RK3328_CRU_PLL_REFDIV_SHIFT);
1284 	reg = HREAD4(sc, base + 0x0008);
1285 	reg &= ~RK3328_CRU_PLL_FRACDIV_MASK;
1286 	reg |= fracdiv << RK3328_CRU_PLL_FRACDIV_SHIFT;
1287 	HWRITE4(sc, base + 0x0008, reg);
1288 
1289 	/* Wait for PLL to stabilize. */
1290 	while ((HREAD4(sc, base + 0x0004) & RK3328_CRU_PLL_PLL_LOCK) == 0)
1291 		delay(10);
1292 
1293 	/* Switch back to normal mode. */
1294 	HWRITE4(sc, RK3328_CRU_CRU_MODE,
1295 	   (RK3328_CRU_CRU_MODE_MASK << 16 |
1296 	   RK3328_CRU_CRU_MODE_NORMAL) << mode_shift);
1297 
1298 	return 0;
1299 }
1300 
1301 uint32_t
1302 rk3328_get_frequency(void *cookie, uint32_t *cells)
1303 {
1304 	struct rkclock_softc *sc = cookie;
1305 	uint32_t idx = cells[0];
1306 
1307 	switch (idx) {
1308 	case RK3328_PLL_APLL:
1309 		return rk3328_get_pll(sc, RK3328_CRU_APLL_CON(0));
1310 		break;
1311 	case RK3328_PLL_DPLL:
1312 		return rk3328_get_pll(sc, RK3328_CRU_DPLL_CON(0));
1313 		break;
1314 	case RK3328_PLL_CPLL:
1315 		return rk3328_get_pll(sc, RK3328_CRU_CPLL_CON(0));
1316 		break;
1317 	case RK3328_PLL_GPLL:
1318 		return rk3328_get_pll(sc, RK3328_CRU_GPLL_CON(0));
1319 		break;
1320 	case RK3328_PLL_NPLL:
1321 		return rk3328_get_pll(sc, RK3328_CRU_NPLL_CON(0));
1322 		break;
1323 	case RK3328_ARMCLK:
1324 		return rk3328_get_armclk(sc);
1325 	case RK3328_XIN24M:
1326 		return 24000000;
1327 	/*
1328 	 * XXX The HDMIPHY and USB480M clocks are external.  Returning
1329 	 * zero here will cause them to be ignored for reparenting
1330 	 * purposes.
1331 	 */
1332 	case RK3328_HDMIPHY:
1333 		return 0;
1334 	case RK3328_USB480M:
1335 		return 0;
1336 	default:
1337 		break;
1338 	}
1339 
1340 	return rkclock_get_frequency(sc, idx);
1341 }
1342 
1343 int
1344 rk3328_set_frequency(void *cookie, uint32_t *cells, uint32_t freq)
1345 {
1346 	struct rkclock_softc *sc = cookie;
1347 	uint32_t idx = cells[0];
1348 	uint32_t reg, mux;
1349 
1350 	switch (idx) {
1351 	case RK3328_PLL_APLL:
1352 		return rk3328_set_frac_pll(sc, RK3328_CRU_APLL_CON(0), freq);
1353 	case RK3328_PLL_DPLL:
1354 		return rk3328_set_pll(sc, RK3328_CRU_DPLL_CON(0), freq);
1355 	case RK3328_PLL_CPLL:
1356 		return rk3328_set_pll(sc, RK3328_CRU_CPLL_CON(0), freq);
1357 	case RK3328_PLL_GPLL:
1358 		return rk3328_set_frac_pll(sc, RK3328_CRU_GPLL_CON(0), freq);
1359 	case RK3328_PLL_NPLL:
1360 		return rk3328_set_pll(sc, RK3328_CRU_NPLL_CON(0), freq);
1361 	case RK3328_ARMCLK:
1362 		return rk3328_set_armclk(sc, freq);
1363 	case RK3328_CLK_UART0:
1364 	case RK3328_CLK_UART1:
1365 	case RK3328_CLK_UART2:
1366 		if (freq == rk3328_get_frequency(sc, &idx))
1367 			return 0;
1368 		break;
1369 	case RK3328_DCLK_LCDC:
1370 		reg = HREAD4(sc, RK3328_CRU_CLKSEL_CON(40));
1371 		mux = (reg & RK3328_CRU_VOP_DCLK_SRC_SEL_MASK) >>
1372 		    RK3328_CRU_VOP_DCLK_SRC_SEL_SHIFT;
1373 		idx = (mux == 0) ? RK3328_HDMIPHY : RK3328_DCLK_LCDC_SRC;
1374 		return rk3328_set_frequency(sc, &idx, freq);
1375 	default:
1376 		break;
1377 	}
1378 
1379 	return rkclock_set_frequency(sc, idx, freq);
1380 }
1381 
1382 int
1383 rk3328_set_parent(void *cookie, uint32_t *cells, uint32_t *pcells)
1384 {
1385 	struct rkclock_softc *sc = cookie;
1386 	uint32_t idx = cells[0];
1387 	uint32_t parent;
1388 
1389 	if (pcells[0] == sc->sc_phandle)
1390 		parent = pcells[1];
1391 	else {
1392 		char name[32];
1393 		int node;
1394 
1395 		node = OF_getnodebyphandle(pcells[0]);
1396 		if (node == 0)
1397 			return -1;
1398 		name[0] = 0;
1399 		OF_getprop(node, "clock-output-names", name, sizeof(name));
1400 		name[sizeof(name) - 1] = 0;
1401 		if (strcmp(name, "xin24m") != 0)
1402 			return -1;
1403 
1404 		parent = RK3328_XIN24M;
1405 	}
1406 
1407 	return rkclock_set_parent(sc, idx, parent);
1408 }
1409 
1410 void
1411 rk3328_enable(void *cookie, uint32_t *cells, int on)
1412 {
1413 	uint32_t idx = cells[0];
1414 
1415 	/*
1416 	 * All clocks are enabled by default, so there is nothing for
1417 	 * us to do until we start disabling clocks.
1418 	 */
1419 	if (!on)
1420 		printf("%s: 0x%08x\n", __func__, idx);
1421 }
1422 
1423 void
1424 rk3328_reset(void *cookie, uint32_t *cells, int on)
1425 {
1426 	struct rkclock_softc *sc = cookie;
1427 	uint32_t idx = cells[0];
1428 	uint32_t mask = (1 << (idx % 16));
1429 
1430 	HWRITE4(sc, RK3328_CRU_SOFTRST_CON(idx / 16),
1431 	    mask << 16 | (on ? mask : 0));
1432 }
1433 
1434 /*
1435  * Rockchip RK3399
1436  */
1437 
1438 struct rkclock rk3399_clocks[] = {
1439 	{
1440 		RK3399_CLK_I2C1, RK3399_CRU_CLKSEL_CON(61),
1441 		SEL(7, 7), DIV(6, 0),
1442 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL }
1443 	},
1444 	{
1445 		RK3399_CLK_I2C2, RK3399_CRU_CLKSEL_CON(62),
1446 		SEL(7, 7), DIV(6, 0),
1447 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL }
1448 	},
1449 	{
1450 		RK3399_CLK_I2C3, RK3399_CRU_CLKSEL_CON(63),
1451 		SEL(7, 7), DIV(6, 0),
1452 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL }
1453 	},
1454 	{
1455 		RK3399_CLK_I2C5, RK3399_CRU_CLKSEL_CON(61),
1456 		SEL(15, 15), DIV(14, 8),
1457 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL }
1458 	},
1459 	{
1460 		RK3399_CLK_I2C6, RK3399_CRU_CLKSEL_CON(62),
1461 		SEL(15, 15), DIV(14, 8),
1462 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL }
1463 	},
1464 	{
1465 		RK3399_CLK_I2C7, RK3399_CRU_CLKSEL_CON(63),
1466 		SEL(15, 15), DIV(14, 8),
1467 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL }
1468 	},
1469 	{
1470 		RK3399_CLK_SDMMC, RK3399_CRU_CLKSEL_CON(16),
1471 		SEL(10, 8), DIV(6, 0),
1472 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL, RK3399_PLL_NPLL,
1473 		  /* RK3399_PLL_PPLL */ 0, /* RK3399_USB_480M */ 0,
1474 		  RK3399_XIN24M }
1475 	},
1476 	{
1477 		RK3399_CLK_SDIO, RK3399_CRU_CLKSEL_CON(15),
1478 		SEL(10, 8), DIV(6, 0),
1479 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL, RK3399_PLL_NPLL,
1480 		  /* RK3399_PLL_PPLL */ 0, /* RK3399_USB_480M */ 0,
1481 		  RK3399_XIN24M }
1482 	},
1483 	{
1484 		RK3399_CLK_TSADC, RK3399_CRU_CLKSEL_CON(27),
1485 		SEL(15, 15), DIV(9, 0),
1486 		{ RK3399_XIN24M, RK3399_CLK_32K }
1487 	},
1488 	{
1489 		RK3399_CLK_UART0, RK3399_CRU_CLKSEL_CON(33),
1490 		SEL(9, 8), 0,
1491 		{ 0, 0, RK3399_XIN24M }
1492 	},
1493 	{
1494 		RK3399_CLK_UART1, RK3399_CRU_CLKSEL_CON(34),
1495 		SEL(9, 8), 0,
1496 		{ 0, 0, RK3399_XIN24M }
1497 	},
1498 	{
1499 		RK3399_CLK_UART2, RK3399_CRU_CLKSEL_CON(35),
1500 		SEL(9, 8), 0,
1501 		{ 0, 0, RK3399_XIN24M }
1502 	},
1503 	{
1504 		RK3399_CLK_UART3, RK3399_CRU_CLKSEL_CON(36),
1505 		SEL(9, 8), 0,
1506 		{ 0, 0, RK3399_XIN24M }
1507 	},
1508 	{
1509 		RK3399_ACLK_PERIPH, RK3399_CRU_CLKSEL_CON(14),
1510 		SEL(7, 7), DIV(4, 0),
1511 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL }
1512 	},
1513 	{
1514 		RK3399_ACLK_PERILP0, RK3399_CRU_CLKSEL_CON(23),
1515 		SEL(7, 7), DIV(4, 0),
1516 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL }
1517 	},
1518 	{
1519 		RK3399_ACLK_VIO, RK3399_CRU_CLKSEL_CON(42),
1520 		SEL(7, 6), DIV(4, 0),
1521 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL, /* RK3399_PLL_PPLL */ }
1522 	},
1523 	{
1524 		RK3399_ACLK_CCI, RK3399_CRU_CLKSEL_CON(5),
1525 		SEL(7, 6), DIV(4, 0),
1526 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL, RK3399_PLL_NPLL,
1527 		  RK3399_PLL_VPLL }
1528 	},
1529 	{
1530 		RK3399_ACLK_HDCP, RK3399_CRU_CLKSEL_CON(42),
1531 		SEL(15, 14), DIV(12, 8),
1532 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL, /* RK3399_PLL_PPLL */ }
1533 	},
1534 	{
1535 		RK3399_ACLK_GIC_PRE, RK3399_CRU_CLKSEL_CON(56),
1536 		SEL(15, 15), DIV(12, 8),
1537 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL }
1538 	},
1539 	{
1540 		RK3399_PCLK_PERIPH, RK3399_CRU_CLKSEL_CON(14),
1541 		0, DIV(14, 12),
1542 		{ RK3399_ACLK_PERIPH }
1543 	},
1544 	{
1545 		RK3399_PCLK_PERILP0, RK3399_CRU_CLKSEL_CON(23),
1546 		0, DIV(14, 12),
1547 		{ RK3399_ACLK_PERILP0 }
1548 	},
1549 	{
1550 		RK3399_PCLK_PERILP1, RK3399_CRU_CLKSEL_CON(25),
1551 		0, DIV(10, 8),
1552 		{ RK3399_HCLK_PERILP1 }
1553 	},
1554 	{
1555 		RK3399_PCLK_DDR, RK3399_CRU_CLKSEL_CON(6),
1556 		SEL(15, 15), DIV(12, 8),
1557 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL }
1558 	},
1559 	{
1560 		RK3399_HCLK_PERIPH, RK3399_CRU_CLKSEL_CON(14),
1561 		0, DIV(9, 8),
1562 		{ RK3399_ACLK_PERIPH }
1563 	},
1564 	{
1565 		RK3399_HCLK_PERILP0, RK3399_CRU_CLKSEL_CON(23),
1566 		0, DIV(9, 8),
1567 		{ RK3399_ACLK_PERILP0 }
1568 	},
1569 	{
1570 		RK3399_HCLK_PERILP1, RK3399_CRU_CLKSEL_CON(25),
1571 		SEL(7, 7), DIV(4, 0),
1572 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL }
1573 	},
1574 	{
1575 		RK3399_HCLK_SDMMC, RK3399_CRU_CLKSEL_CON(13),
1576 		SEL(15, 15), DIV(12, 8),
1577 		{ RK3399_PLL_CPLL, RK3399_PLL_GPLL }
1578 	},
1579 	{
1580 		/* Sentinel */
1581 	}
1582 };
1583 
1584 /* Some of our parent clocks live in the PMUCRU. */
1585 struct rkclock_softc *rk3399_pmucru_sc;
1586 
1587 void
1588 rk3399_init(struct rkclock_softc *sc)
1589 {
1590 	int i;
1591 
1592 	/* PMUCRU instance should attach before us. */
1593 	KASSERT(rk3399_pmucru_sc != NULL);
1594 
1595 	/*
1596 	 * The U-Boot shipped on the Theobroma Systems RK3399-Q7
1597 	 * module is buggy and sets the parent of the clock for the
1598 	 * "big" cluster to LPLL.  Undo that mistake here such that
1599 	 * the clocks of both clusters are independent.
1600 	 */
1601 	HWRITE4(sc, RK3399_CRU_CLKSEL_CON(2),
1602 	    RK3399_CRU_CORE_PLL_SEL_MASK << 16 |
1603 	    RK3399_CRU_CORE_PLL_SEL_BPLL);
1604 
1605 	/* The code below assumes all clocks are enabled.  Check this!. */
1606 	for (i = 0; i <= 34; i++) {
1607 		if (HREAD4(sc, RK3399_CRU_CLKGATE_CON(i)) != 0x00000000) {
1608 			printf("CRU_CLKGATE_CON%d: 0x%08x\n", i,
1609 			    HREAD4(sc, RK3399_CRU_CLKGATE_CON(i)));
1610 		}
1611 	}
1612 
1613 	sc->sc_clocks = rk3399_clocks;
1614 }
1615 
1616 uint32_t
1617 rk3399_get_pll(struct rkclock_softc *sc, bus_size_t base)
1618 {
1619 	uint32_t fbdiv, postdiv1, postdiv2, refdiv;
1620 	uint32_t pll_work_mode;
1621 	uint32_t reg;
1622 
1623 	reg = HREAD4(sc, base + 0x000c);
1624 	pll_work_mode = reg & RK3399_CRU_PLL_PLL_WORK_MODE_MASK;
1625 	if (pll_work_mode == RK3399_CRU_PLL_PLL_WORK_MODE_SLOW)
1626 		return 24000000;
1627 	if (pll_work_mode == RK3399_CRU_PLL_PLL_WORK_MODE_DEEP_SLOW)
1628 		return 32768;
1629 
1630 	reg = HREAD4(sc, base + 0x0000);
1631 	fbdiv = (reg & RK3399_CRU_PLL_FBDIV_MASK) >>
1632 	    RK3399_CRU_PLL_FBDIV_SHIFT;
1633 	reg = HREAD4(sc, base + 0x0004);
1634 	postdiv2 = (reg & RK3399_CRU_PLL_POSTDIV2_MASK) >>
1635 	    RK3399_CRU_PLL_POSTDIV2_SHIFT;
1636 	postdiv1 = (reg & RK3399_CRU_PLL_POSTDIV1_MASK) >>
1637 	    RK3399_CRU_PLL_POSTDIV1_SHIFT;
1638 	refdiv = (reg & RK3399_CRU_PLL_REFDIV_MASK) >>
1639 	    RK3399_CRU_PLL_REFDIV_SHIFT;
1640 	return 24000000ULL * fbdiv / refdiv / postdiv1 / postdiv2;
1641 }
1642 
1643 int
1644 rk3399_set_pll(struct rkclock_softc *sc, bus_size_t base, uint32_t freq)
1645 {
1646 	uint32_t fbdiv, postdiv1, postdiv2, refdiv;
1647 
1648 	/*
1649 	 * It is not clear whether all combinations of the clock
1650 	 * dividers result in a stable clock.  Therefore this function
1651 	 * only supports a limited set of PLL clock rates.  For now
1652 	 * this set covers all the CPU frequencies supported by the
1653 	 * Linux kernel.
1654 	 */
1655 	switch (freq) {
1656 	case 2208000000U:
1657 	case 2184000000U:
1658 	case 2088000000U:
1659 	case 2040000000U:
1660 	case 2016000000U:
1661 	case 1992000000U:
1662 	case 1896000000U:
1663 	case 1800000000U:
1664 	case 1704000000U:
1665 	case 1608000000U:
1666 	case 1512000000U:
1667 	case 1488000000U:
1668 	case 1416000000U:
1669 	case 1200000000U:
1670 		postdiv1 = postdiv2 = refdiv = 1;
1671 		break;
1672 	case 1008000000U:
1673 	case 816000000U:
1674 	case 696000000U:
1675 		postdiv1 = 2; postdiv2 = refdiv = 1;
1676 		break;
1677 	case 676000000U:
1678 		postdiv1 = 2; postdiv2 = 1; refdiv = 3;
1679 		break;
1680 	case 1000000000U:
1681 	case 800000000U:
1682 	case 600000000U:
1683 		postdiv1 = 3; postdiv2 = refdiv = 1;
1684 		break;
1685 	case 594000000U:
1686 		postdiv1 = 4; postdiv2 = refdiv = 1;
1687 		break;
1688 	case 408000000U:
1689 		postdiv1 = postdiv2 = 2; refdiv = 1;
1690 		break;
1691 	case 216000000U:
1692 		postdiv1 = 4; postdiv2 = 2; refdiv = 1;
1693 		break;
1694 	case 96000000U:
1695 		postdiv1 = postdiv2 = 4; refdiv = 1;
1696 		break;
1697 	default:
1698 		printf("%s: %d Hz\n", __func__, freq);
1699 		return -1;
1700 	}
1701 
1702 	/* Calculate feedback divider. */
1703 	fbdiv = freq * postdiv1 * postdiv2 * refdiv / 24000000;
1704 
1705 	/*
1706 	 * Select slow mode to guarantee a stable clock while we're
1707 	 * adjusting the PLL.
1708 	 */
1709 	HWRITE4(sc, base + 0x000c,
1710 	    RK3399_CRU_PLL_PLL_WORK_MODE_MASK << 16 |
1711 	    RK3399_CRU_PLL_PLL_WORK_MODE_SLOW);
1712 
1713 	/* Set PLL rate. */
1714 	HWRITE4(sc, base + 0x0000,
1715 	    RK3399_CRU_PLL_FBDIV_MASK << 16 |
1716 	    fbdiv << RK3399_CRU_PLL_FBDIV_SHIFT);
1717 	HWRITE4(sc, base + 0x0004,
1718 	    RK3399_CRU_PLL_POSTDIV2_MASK << 16 |
1719 	    postdiv2 << RK3399_CRU_PLL_POSTDIV2_SHIFT |
1720 	    RK3399_CRU_PLL_POSTDIV1_MASK << 16 |
1721 	    postdiv1 << RK3399_CRU_PLL_POSTDIV1_SHIFT |
1722 	    RK3399_CRU_PLL_REFDIV_MASK << 16 |
1723 	    refdiv << RK3399_CRU_PLL_REFDIV_SHIFT);
1724 
1725 	/* Wait for PLL to stabilize. */
1726 	while ((HREAD4(sc, base + 0x0008) & RK3399_CRU_PLL_PLL_LOCK) == 0)
1727 		delay(10);
1728 
1729 	/* Switch back to normal mode. */
1730 	HWRITE4(sc, base + 0x000c,
1731 	    RK3399_CRU_PLL_PLL_WORK_MODE_MASK << 16 |
1732 	    RK3399_CRU_PLL_PLL_WORK_MODE_NORMAL);
1733 
1734 	return 0;
1735 }
1736 
1737 uint32_t
1738 rk3399_armclk_parent(uint32_t mux)
1739 {
1740 	switch (mux) {
1741 	case 0:
1742 		return RK3399_PLL_ALPLL;
1743 	case 1:
1744 		return RK3399_PLL_ABPLL;
1745 	case 2:
1746 		return RK3399_PLL_DPLL;
1747 	case 3:
1748 		return RK3399_PLL_GPLL;
1749 	}
1750 
1751 	return 0;
1752 }
1753 
1754 uint32_t
1755 rk3399_get_armclk(struct rkclock_softc *sc, bus_size_t clksel)
1756 {
1757 	uint32_t reg, mux, div_con;
1758 	uint32_t idx;
1759 
1760 	reg = HREAD4(sc, clksel);
1761 	mux = (reg & RK3399_CRU_CORE_PLL_SEL_MASK) >>
1762 	    RK3399_CRU_CORE_PLL_SEL_SHIFT;
1763 	div_con = (reg & RK3399_CRU_CLK_CORE_DIV_CON_MASK) >>
1764 	    RK3399_CRU_CLK_CORE_DIV_CON_SHIFT;
1765 	idx = rk3399_armclk_parent(mux);
1766 
1767 	return rk3399_get_frequency(sc, &idx) / (div_con + 1);
1768 }
1769 
1770 int
1771 rk3399_set_armclk(struct rkclock_softc *sc, bus_size_t clksel, uint32_t freq)
1772 {
1773 	uint32_t reg, mux;
1774 	uint32_t old_freq, div;
1775 	uint32_t idx;
1776 
1777 	old_freq = rk3399_get_armclk(sc, clksel);
1778 	if (freq == old_freq)
1779 		return 0;
1780 
1781 	reg = HREAD4(sc, clksel);
1782 	mux = (reg & RK3399_CRU_CORE_PLL_SEL_MASK) >>
1783 	    RK3399_CRU_CORE_PLL_SEL_SHIFT;
1784 	idx = rk3399_armclk_parent(mux);
1785 
1786 	/* Keep the atclk_core and pclk_dbg clocks at or below 200 MHz. */
1787 	div = 1;
1788 	while (freq / (div + 1) > 200000000)
1789 		div++;
1790 
1791 	/* When ramping up, set clock dividers first. */
1792 	if (freq > old_freq) {
1793 		HWRITE4(sc, clksel,
1794 		    RK3399_CRU_CLK_CORE_DIV_CON_MASK << 16 |
1795 		    0 << RK3399_CRU_CLK_CORE_DIV_CON_SHIFT |
1796 		    RK3399_CRU_ACLKM_CORE_DIV_CON_MASK << 16 |
1797 		    1 << RK3399_CRU_ACLKM_CORE_DIV_CON_SHIFT);
1798 		HWRITE4(sc, clksel + 0x0004,
1799 		    RK3399_CRU_PCLK_DBG_DIV_CON_MASK << 16 |
1800 		    div << RK3399_CRU_PCLK_DBG_DIV_CON_SHIFT |
1801 		    RK3399_CRU_ATCLK_CORE_DIV_CON_MASK << 16 |
1802 		    div << RK3399_CRU_ATCLK_CORE_DIV_CON_SHIFT);
1803 	}
1804 
1805 	rk3399_set_frequency(sc, &idx, freq);
1806 
1807 	/* When ramping down, set clock dividers last. */
1808 	if (freq < old_freq) {
1809 		HWRITE4(sc, clksel,
1810 		    RK3399_CRU_CLK_CORE_DIV_CON_MASK << 16 |
1811 		    0 << RK3399_CRU_CLK_CORE_DIV_CON_SHIFT |
1812 		    RK3399_CRU_ACLKM_CORE_DIV_CON_MASK << 16 |
1813 		    1 << RK3399_CRU_ACLKM_CORE_DIV_CON_SHIFT);
1814 		HWRITE4(sc, clksel + 0x0004,
1815 		    RK3399_CRU_PCLK_DBG_DIV_CON_MASK << 16 |
1816 		    div << RK3399_CRU_PCLK_DBG_DIV_CON_SHIFT |
1817 		    RK3399_CRU_ATCLK_CORE_DIV_CON_MASK << 16 |
1818 		    div << RK3399_CRU_ATCLK_CORE_DIV_CON_SHIFT);
1819 	}
1820 
1821 	return 0;
1822 }
1823 
1824 uint32_t
1825 rk3399_get_frequency(void *cookie, uint32_t *cells)
1826 {
1827 	struct rkclock_softc *sc = cookie;
1828 	uint32_t idx = cells[0];
1829 
1830 	switch (idx) {
1831 	case RK3399_PLL_ALPLL:
1832 		return rk3399_get_pll(sc, RK3399_CRU_LPLL_CON(0));
1833 	case RK3399_PLL_ABPLL:
1834 		return rk3399_get_pll(sc, RK3399_CRU_BPLL_CON(0));
1835 	case RK3399_PLL_DPLL:
1836 		return rk3399_get_pll(sc, RK3399_CRU_DPLL_CON(0));
1837 	case RK3399_PLL_CPLL:
1838 		return rk3399_get_pll(sc, RK3399_CRU_CPLL_CON(0));
1839 	case RK3399_PLL_GPLL:
1840 		return rk3399_get_pll(sc, RK3399_CRU_GPLL_CON(0));
1841 	case RK3399_PLL_NPLL:
1842 		return rk3399_get_pll(sc, RK3399_CRU_NPLL_CON(0));
1843 	case RK3399_PLL_VPLL:
1844 		return rk3399_get_pll(sc, RK3399_CRU_VPLL_CON(0));
1845 	case RK3399_ARMCLKL:
1846 		return rk3399_get_armclk(sc, RK3399_CRU_CLKSEL_CON(0));
1847 	case RK3399_ARMCLKB:
1848 		return rk3399_get_armclk(sc, RK3399_CRU_CLKSEL_CON(2));
1849 	case RK3399_XIN24M:
1850 		return 24000000;
1851 	case RK3399_CLK_32K:
1852 		return 32768;
1853 	default:
1854 		break;
1855 	}
1856 
1857 	return rkclock_get_frequency(sc, idx);
1858 }
1859 
1860 int
1861 rk3399_set_frequency(void *cookie, uint32_t *cells, uint32_t freq)
1862 {
1863 	struct rkclock_softc *sc = cookie;
1864 	uint32_t idx = cells[0];
1865 
1866 	switch (idx) {
1867 	case RK3399_PLL_ALPLL:
1868 		return rk3399_set_pll(sc, RK3399_CRU_LPLL_CON(0), freq);
1869 	case RK3399_PLL_ABPLL:
1870 		return rk3399_set_pll(sc, RK3399_CRU_BPLL_CON(0), freq);
1871 	case RK3399_PLL_CPLL:
1872 		return rk3399_set_pll(sc, RK3399_CRU_CPLL_CON(0), freq);
1873 	case RK3399_PLL_GPLL:
1874 		return rk3399_set_pll(sc, RK3399_CRU_GPLL_CON(0), freq);
1875 	case RK3399_PLL_NPLL:
1876 		return rk3399_set_pll(sc, RK3399_CRU_NPLL_CON(0), freq);
1877 	case RK3399_ARMCLKL:
1878 		return rk3399_set_armclk(sc, RK3399_CRU_CLKSEL_CON(0), freq);
1879 	case RK3399_ARMCLKB:
1880 		return rk3399_set_armclk(sc, RK3399_CRU_CLKSEL_CON(2), freq);
1881 	default:
1882 		break;
1883 	}
1884 
1885 	return rkclock_set_frequency(sc, idx, freq);
1886 }
1887 
1888 void
1889 rk3399_enable(void *cookie, uint32_t *cells, int on)
1890 {
1891 	uint32_t idx = cells[0];
1892 
1893 	/*
1894 	 * All clocks are enabled by default, so there is nothing for
1895 	 * us to do until we start disabling clocks.
1896 	 */
1897 	if (!on)
1898 		printf("%s: 0x%08x\n", __func__, idx);
1899 }
1900 
1901 void
1902 rk3399_reset(void *cookie, uint32_t *cells, int on)
1903 {
1904 	struct rkclock_softc *sc = cookie;
1905 	uint32_t idx = cells[0];
1906 	uint32_t mask = (1 << (idx % 16));
1907 
1908 	HWRITE4(sc, RK3399_CRU_SOFTRST_CON(idx / 16),
1909 	    mask << 16 | (on ? mask : 0));
1910 }
1911 
1912 /* PMUCRU */
1913 
1914 struct rkclock rk3399_pmu_clocks[] = {
1915 	{
1916 		RK3399_CLK_I2C0, RK3399_PMUCRU_CLKSEL_CON(2),
1917 		0, DIV(6, 0),
1918 		{ RK3399_PLL_PPLL }
1919 	},
1920 	{
1921 		RK3399_CLK_I2C4, RK3399_PMUCRU_CLKSEL_CON(3),
1922 		0, DIV(6, 0),
1923 		{ RK3399_PLL_PPLL }
1924 	},
1925 	{
1926 		RK3399_CLK_I2C8, RK3399_PMUCRU_CLKSEL_CON(2),
1927 		0, DIV(14, 8),
1928 		{ RK3399_PLL_PPLL }
1929 	},
1930 	{
1931 		/* Sentinel */
1932 	}
1933 };
1934 
1935 void
1936 rk3399_pmu_init(struct rkclock_softc *sc)
1937 {
1938 	sc->sc_clocks = rk3399_pmu_clocks;
1939 	rk3399_pmucru_sc = sc;
1940 }
1941 
1942 uint32_t
1943 rk3399_pmu_get_frequency(void *cookie, uint32_t *cells)
1944 {
1945 	struct rkclock_softc *sc = cookie;
1946 	uint32_t idx = cells[0];
1947 
1948 	switch (idx) {
1949 	case RK3399_PLL_PPLL:
1950 		return rk3399_get_pll(sc, RK3399_PMUCRU_PPLL_CON(0));
1951 	default:
1952 		break;
1953 	}
1954 
1955 	return rkclock_get_frequency(sc, idx);
1956 }
1957 
1958 int
1959 rk3399_pmu_set_frequency(void *cookie, uint32_t *cells, uint32_t freq)
1960 {
1961 	struct rkclock_softc *sc = cookie;
1962 	uint32_t idx = cells[0];
1963 
1964 	switch (idx) {
1965 	case RK3399_PLL_PPLL:
1966 		return rk3399_set_pll(sc, RK3399_PMUCRU_PPLL_CON(0), freq);
1967 		break;
1968 	default:
1969 		break;
1970 	}
1971 
1972 	return rkclock_set_frequency(sc, idx, freq);
1973 }
1974 
1975 void
1976 rk3399_pmu_enable(void *cookie, uint32_t *cells, int on)
1977 {
1978 	uint32_t idx = cells[0];
1979 
1980 	switch (idx) {
1981 	case RK3399_CLK_I2C0:
1982 	case RK3399_CLK_I2C4:
1983 	case RK3399_CLK_I2C8:
1984 	case RK3399_PCLK_I2C0:
1985 	case RK3399_PCLK_I2C4:
1986 	case RK3399_PCLK_I2C8:
1987 		/* Enabled by default. */
1988 		break;
1989 	default:
1990 		printf("%s: 0x%08x\n", __func__, idx);
1991 		break;
1992 	}
1993 }
1994 
1995 void
1996 rk3399_pmu_reset(void *cookie, uint32_t *cells, int on)
1997 {
1998 	uint32_t idx = cells[0];
1999 
2000 	printf("%s: 0x%08x\n", __func__, idx);
2001 }
2002