xref: /openbsd-src/sys/dev/fdt/rkclock.c (revision c0dd97bfcad3dab6c31ec12b9de1274fd2d2f993)
1 /*	$OpenBSD: rkclock.c,v 1.16 2017/09/02 08:35:08 jsg Exp $	*/
2 /*
3  * Copyright (c) 2017 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_CPLL_CON(i)		(0x0020 + (i) * 4)
33 #define RK3288_CRU_GPLL_CON(i)		(0x0030 + (i) * 4)
34 #define RK3288_CRU_CLKSEL_CON(i)	(0x0060 + (i) * 4)
35 
36 /* RK3399 registers */
37 #define RK3399_CRU_LPLL_CON(i)		(0x0000 + (i) * 4)
38 #define RK3399_CRU_BPLL_CON(i)		(0x0020 + (i) * 4)
39 #define RK3399_CRU_DPLL_CON(i)		(0x0020 + (i) * 4)
40 #define RK3399_CRU_CPLL_CON(i)		(0x0060 + (i) * 4)
41 #define RK3399_CRU_GPLL_CON(i)		(0x0080 + (i) * 4)
42 #define RK3399_CRU_NPLL_CON(i)		(0x00a0 + (i) * 4)
43 #define  RK3399_CRU_PLL_FBDIV_MASK		(0xfff << 0)
44 #define  RK3399_CRU_PLL_FBDIV_SHIFT		0
45 #define  RK3399_CRU_PLL_POSTDIV2_MASK		(0x7 << 12)
46 #define  RK3399_CRU_PLL_POSTDIV2_SHIFT		12
47 #define  RK3399_CRU_PLL_POSTDIV1_MASK		(0x7 << 8)
48 #define  RK3399_CRU_PLL_POSTDIV1_SHIFT		8
49 #define  RK3399_CRU_PLL_REFDIV_MASK		(0x3f << 0)
50 #define  RK3399_CRU_PLL_REFDIV_SHIFT		0
51 #define  RK3399_CRU_PLL_PLL_WORK_MODE_MASK	(0x3 << 8)
52 #define  RK3399_CRU_PLL_PLL_WORK_MODE_SLOW	(0x0 << 8)
53 #define  RK3399_CRU_PLL_PLL_WORK_MODE_NORMAL	(0x1 << 8)
54 #define  RK3399_CRU_PLL_PLL_WORK_MODE_DEEP_SLOW	(0x2 << 8)
55 #define  RK3399_CRU_PLL_PLL_LOCK		(1U << 31)
56 #define RK3399_CRU_CLKSEL_CON(i)	(0x0100 + (i) * 4)
57 #define  RK3399_CRU_ACLKM_CORE_DIV_CON_MASK	(0x1f << 8)
58 #define  RK3399_CRU_ACLKM_CORE_DIV_CON_SHIFT	8
59 #define  RK3399_CRU_CORE_PLL_SEL_MASK		(0x3 << 6)
60 #define  RK3399_CRU_CORE_PLL_SEL_SHIFT		6
61 #define  RK3399_CRU_CLK_CORE_DIV_CON_MASK	(0x1f << 0)
62 #define  RK3399_CRU_CLK_CORE_DIV_CON_SHIFT	0
63 #define  RK3399_CRU_PCLK_DBG_DIV_CON_MASK	(0x1f << 8)
64 #define  RK3399_CRU_PCLK_DBG_DIV_CON_SHIFT	8
65 #define  RK3399_CRU_ATCLK_CORE_DIV_CON_MASK	(0x1f << 0)
66 #define  RK3399_CRU_ATCLK_CORE_DIV_CON_SHIFT	0
67 #define RK3399_CRU_CLKGATE_CON(i)	(0x0300 + (i) * 4)
68 #define RK3399_CRU_SOFTRST_CON(i)	(0x0400 + (i) * 4)
69 #define RK3399_CRU_SDMMC_CON(i)		(0x0580 + (i) * 4)
70 
71 #define RK3399_PMUCRU_PPLL_CON(i)	(0x0000 + (i) * 4)
72 #define RK3399_PMUCRU_CLKSEL_CON(i)	(0x0080 + (i) * 4)
73 
74 #include "rkclock_clocks.h"
75 
76 #define HREAD4(sc, reg)							\
77 	(bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg)))
78 #define HWRITE4(sc, reg, val)						\
79 	bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
80 #define HSET4(sc, reg, bits)						\
81 	HWRITE4((sc), (reg), HREAD4((sc), (reg)) | (bits))
82 #define HCLR4(sc, reg, bits)						\
83 	HWRITE4((sc), (reg), HREAD4((sc), (reg)) & ~(bits))
84 
85 struct rkclock_softc {
86 	struct device		sc_dev;
87 	bus_space_tag_t		sc_iot;
88 	bus_space_handle_t	sc_ioh;
89 
90 	struct clock_device	sc_cd;
91 	struct reset_device	sc_rd;
92 };
93 
94 int rkclock_match(struct device *, void *, void *);
95 void rkclock_attach(struct device *, struct device *, void *);
96 
97 struct cfattach	rkclock_ca = {
98 	sizeof (struct rkclock_softc), rkclock_match, rkclock_attach
99 };
100 
101 struct cfdriver rkclock_cd = {
102 	NULL, "rkclock", DV_DULL
103 };
104 
105 struct rkclock_softc *rkclock_cpuspeed_sc;
106 
107 uint32_t rk3288_get_frequency(void *, uint32_t *);
108 int	rk3288_set_frequency(void *, uint32_t *, uint32_t);
109 void	rk3288_enable(void *, uint32_t *, int);
110 void	rk3288_reset(void *, uint32_t *, int);
111 
112 void	rk3399_init(struct rkclock_softc *);
113 uint32_t rk3399_get_frequency(void *, uint32_t *);
114 int	rk3399_set_frequency(void *, uint32_t *, uint32_t);
115 void	rk3399_enable(void *, uint32_t *, int);
116 void	rk3399_reset(void *, uint32_t *, int);
117 int	rk3399_cpuspeed(int *);
118 
119 void	rk3399_pmu_init(struct rkclock_softc *);
120 uint32_t rk3399_pmu_get_frequency(void *, uint32_t *);
121 int	rk3399_pmu_set_frequency(void *, uint32_t *, uint32_t);
122 void	rk3399_pmu_enable(void *, uint32_t *, int);
123 void	rk3399_pmu_reset(void *, uint32_t *, int);
124 
125 struct rkclock_compat {
126 	const char *compat;
127 	void	(*init)(struct rkclock_softc *);
128 	void	(*enable)(void *, uint32_t *, int);
129 	uint32_t (*get_frequency)(void *, uint32_t *);
130 	int	(*set_frequency)(void *, uint32_t *, uint32_t);
131 	void	(*reset)(void *, uint32_t *, int);
132 };
133 
134 struct rkclock_compat rkclock_compat[] = {
135 	{
136 		"rockchip,rk3288-cru", NULL,
137 		rk3288_enable, rk3288_get_frequency,
138 		rk3288_set_frequency, rk3288_reset
139 	},
140 	{
141 		"rockchip,rk3399-cru", rk3399_init,
142 		rk3399_enable, rk3399_get_frequency,
143 		rk3399_set_frequency, rk3399_reset,
144 	},
145 	{
146 		"rockchip,rk3399-pmucru", rk3399_pmu_init,
147 		rk3399_pmu_enable, rk3399_pmu_get_frequency,
148 		rk3399_pmu_set_frequency, rk3399_pmu_reset
149 	}
150 };
151 
152 int
153 rkclock_match(struct device *parent, void *match, void *aux)
154 {
155 	struct fdt_attach_args *faa = aux;
156 	int i;
157 
158 	for (i = 0; i < nitems(rkclock_compat); i++) {
159 		if (OF_is_compatible(faa->fa_node, rkclock_compat[i].compat))
160 			return 1;
161 	}
162 
163 	return 0;
164 }
165 
166 void
167 rkclock_attach(struct device *parent, struct device *self, void *aux)
168 {
169 	struct rkclock_softc *sc = (struct rkclock_softc *)self;
170 	struct fdt_attach_args *faa = aux;
171 	int i;
172 
173 	if (faa->fa_nreg < 1) {
174 		printf(": no registers\n");
175 		return;
176 	}
177 
178 	sc->sc_iot = faa->fa_iot;
179 
180 	if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr,
181 	    faa->fa_reg[0].size, 0, &sc->sc_ioh)) {
182 		printf(": can't map registers\n");
183 		return;
184 	}
185 
186 	printf("\n");
187 
188 	for (i = 0; i < nitems(rkclock_compat); i++) {
189 		if (OF_is_compatible(faa->fa_node, rkclock_compat[i].compat)) {
190 			break;
191 		}
192 	}
193 	KASSERT(i < nitems(rkclock_compat));
194 
195 	if (rkclock_compat[i].init)
196 		rkclock_compat[i].init(sc);
197 
198 	sc->sc_cd.cd_node = faa->fa_node;
199 	sc->sc_cd.cd_cookie = sc;
200 	sc->sc_cd.cd_enable = rkclock_compat[i].enable;
201 	sc->sc_cd.cd_get_frequency = rkclock_compat[i].get_frequency;
202 	sc->sc_cd.cd_set_frequency = rkclock_compat[i].set_frequency;
203 	clock_register(&sc->sc_cd);
204 
205 	sc->sc_rd.rd_node = faa->fa_node;
206 	sc->sc_rd.rd_cookie = sc;
207 	sc->sc_rd.rd_reset = rkclock_compat[i].reset;
208 	reset_register(&sc->sc_rd);
209 }
210 
211 /*
212  * Rockchip RK3288
213  */
214 
215 uint32_t
216 rk3288_get_pll(struct rkclock_softc *sc, bus_size_t base)
217 {
218 	uint32_t clkod, clkr, clkf;
219 	uint32_t reg;
220 
221 	reg = HREAD4(sc, base);
222 	clkod = (reg >> 0) & 0xf;
223 	clkr = (reg >> 8) & 0x3f;
224 	reg = HREAD4(sc, base + 4);
225 	clkf = (reg >> 0) & 0x1fff;
226 	return 24000000ULL * (clkf + 1) / (clkr + 1) / (clkod + 1);
227 }
228 
229 uint32_t
230 rk3288_get_frequency(void *cookie, uint32_t *cells)
231 {
232 	struct rkclock_softc *sc = cookie;
233 	uint32_t idx = cells[0];
234 	uint32_t reg, mux, div_con, aclk_div_con;
235 
236 	switch (idx) {
237 	case RK3288_PLL_CPLL:
238 		return rk3288_get_pll(sc, RK3288_CRU_CPLL_CON(0));
239 	case RK3288_PLL_GPLL:
240 		return rk3288_get_pll(sc, RK3288_CRU_GPLL_CON(0));
241 	case RK3288_CLK_SDMMC:
242 		reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(11));
243 		mux = (reg >> 6) & 0x3;
244 		div_con = reg & 0x3f;
245 		switch (mux) {
246 		case 0:
247 			idx = RK3288_PLL_CPLL;
248 			break;
249 		case 1:
250 			idx = RK3288_PLL_GPLL;
251 			break;
252 		case 2:
253 			return 24000000 / (div_con + 1);
254 		default:
255 			return 0;
256 		}
257 		return rk3288_get_frequency(sc, &idx) / (div_con + 1);
258 		break;
259 	case RK3288_CLK_UART0:
260 		reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(13));
261 		mux = (reg >> 8) & 0x3;
262 		div_con = reg & 0x7f;
263 		if (mux == 2)
264 			return 24000000 / (div_con + 1);
265 		break;
266 	case RK3288_CLK_UART1:
267 		reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(14));
268 		mux = (reg >> 8) & 0x3;
269 		div_con = reg & 0x7f;
270 		if (mux == 2)
271 			return 24000000 / (div_con + 1);
272 		break;
273 	case RK3288_CLK_UART2:
274 		reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(15));
275 		mux = (reg >> 8) & 0x3;
276 		div_con = reg & 0x7f;
277 		if (mux == 2)
278 			return 24000000 / (div_con + 1);
279 		break;
280 	case RK3288_CLK_UART3:
281 		reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(16));
282 		mux = (reg >> 8) & 0x3;
283 		div_con = reg & 0x7f;
284 		if (mux == 2)
285 			return 24000000 / (div_con + 1);
286 		break;
287 	case RK3288_CLK_UART4:
288 		reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(3));
289 		mux = (reg >> 8) & 0x3;
290 		div_con = reg & 0x7f;
291 		if (mux == 2)
292 			return 24000000 / (div_con + 1);
293 		break;
294 	case RK3288_PCLK_I2C0:
295 	case RK3288_PCLK_I2C2:
296 		reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(1));
297 		mux = (reg >> 15) & 0x1;
298 		/* pd_bus_pclk_div_con */
299 		div_con = (reg >> 12) & 0x7;
300 		if (mux == 1)
301 			idx = RK3288_PLL_GPLL;
302 		else
303 			idx = RK3288_PLL_CPLL;
304 		return rk3288_get_frequency(sc, &idx) / (div_con + 1);
305 	case RK3288_PCLK_I2C1:
306 	case RK3288_PCLK_I2C3:
307 	case RK3288_PCLK_I2C4:
308 	case RK3288_PCLK_I2C5:
309 		reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(10));
310 		mux = (reg >> 15) & 0x1;
311 		/* peri_pclk_div_con */
312 		div_con = (reg >> 12) & 0x3;
313 		/* peri_aclk_div_con */
314 		aclk_div_con = reg & 0xf;
315 		if (mux == 1)
316 			idx = RK3288_PLL_GPLL;
317 		else
318 			idx = RK3288_PLL_CPLL;
319 		return (rk3288_get_frequency(sc, &idx) / (aclk_div_con + 1)) >>
320 		    div_con;
321 	default:
322 		break;
323 	}
324 
325 	printf("%s: 0x%08x\n", __func__, idx);
326 	return 0;
327 }
328 
329 int
330 rk3288_set_frequency(void *cookie, uint32_t *cells, uint32_t freq)
331 {
332 	uint32_t idx = cells[0];
333 
334 	printf("%s: 0x%08x\n", __func__, idx);
335 	return -1;
336 }
337 
338 void
339 rk3288_enable(void *cookie, uint32_t *cells, int on)
340 {
341 	uint32_t idx = cells[0];
342 
343 	switch (idx) {
344 	case RK3288_CLK_SDMMC:
345 	case RK3288_CLK_UART0:
346 	case RK3288_CLK_UART1:
347 	case RK3288_CLK_UART2:
348 	case RK3288_CLK_UART3:
349 	case RK3288_CLK_UART4:
350 	case RK3288_CLK_MAC_RX:
351 	case RK3288_CLK_MAC_TX:
352 	case RK3288_CLK_SDMMC_DRV:
353 	case RK3288_CLK_SDMMC_SAMPLE:
354 	case RK3288_CLK_MAC:
355 	case RK3288_ACLK_GMAC:
356 	case RK3288_PCLK_GMAC:
357 	case RK3288_PCLK_I2C0:
358 	case RK3288_PCLK_I2C1:
359 	case RK3288_PCLK_I2C2:
360 	case RK3288_PCLK_I2C3:
361 	case RK3288_PCLK_I2C4:
362 	case RK3288_PCLK_I2C5:
363 	case RK3288_HCLK_HOST0:
364 	case RK3288_HCLK_SDMMC:
365 		/* Enabled by default. */
366 		break;
367 	default:
368 		printf("%s: 0x%08x\n", __func__, idx);
369 		break;
370 	}
371 }
372 
373 void
374 rk3288_reset(void *cookie, uint32_t *cells, int on)
375 {
376 	uint32_t idx = cells[0];
377 
378 	printf("%s: 0x%08x\n", __func__, idx);
379 }
380 
381 /*
382  * Rockchip RK3399
383  */
384 
385 /* Some of our parent clocks live in the PMUCRU. */
386 struct rkclock_softc *rk3399_pmucru_sc;
387 
388 void
389 rk3399_init(struct rkclock_softc *sc)
390 {
391 	int node;
392 
393 	rkclock_cpuspeed_sc = sc;
394 	cpu_cpuspeed = rk3399_cpuspeed;
395 
396 	/* PMUCRU instance should attach before us. */
397 	KASSERT(rk3399_pmucru_sc != NULL);
398 
399 	/*
400 	 * Since the hardware comes up with a really conservative CPU
401 	 * clock frequency, and U-Boot doesn't set it to a more
402 	 * reasonable default, try to do so here.  These defaults were
403 	 * chosen assuming that the voltage for both clusters is at
404 	 * least 1.0 V.  Only do this on the Firefly-RK3399 for now
405 	 * where this is likely to be true given the default voltages
406 	 * for the regulators on that board.
407 	 */
408 	node = OF_finddevice("/");
409 	if (OF_is_compatible(node, "firefly,firefly-rk3399")) {
410 		uint32_t idx;
411 
412 		/* Run the "LITTLE" cluster at 1.2 GHz. */
413 		idx = RK3399_ARMCLKL;
414 		rk3399_set_frequency(sc, &idx, 1200000000);
415 
416 #ifdef MULTIPROCESSOR
417 		/* Switch PLL of the "big" cluster into normal mode. */
418 		HWRITE4(sc, RK3399_CRU_BPLL_CON(3),
419 		    RK3399_CRU_PLL_PLL_WORK_MODE_MASK << 16 |
420 		    RK3399_CRU_PLL_PLL_WORK_MODE_NORMAL);
421 #endif
422 	}
423 }
424 
425 uint32_t
426 rk3399_get_pll(struct rkclock_softc *sc, bus_size_t base)
427 {
428 	uint32_t fbdiv, postdiv1, postdiv2, refdiv;
429 	uint32_t pll_work_mode;
430 	uint32_t reg;
431 
432 	reg = HREAD4(sc, base + 0x000c);
433 	pll_work_mode = reg & RK3399_CRU_PLL_PLL_WORK_MODE_MASK;
434 	if (pll_work_mode == RK3399_CRU_PLL_PLL_WORK_MODE_SLOW)
435 		return 24000000;
436 	if (pll_work_mode == RK3399_CRU_PLL_PLL_WORK_MODE_DEEP_SLOW)
437 		return 32768;
438 
439 	reg = HREAD4(sc, base + 0x0000);
440 	fbdiv = (reg & RK3399_CRU_PLL_FBDIV_MASK) >>
441 	    RK3399_CRU_PLL_FBDIV_SHIFT;
442 	reg = HREAD4(sc, base + 0x0004);
443 	postdiv2 = (reg & RK3399_CRU_PLL_POSTDIV2_MASK) >>
444 	    RK3399_CRU_PLL_POSTDIV2_SHIFT;
445 	postdiv1 = (reg & RK3399_CRU_PLL_POSTDIV1_MASK) >>
446 	    RK3399_CRU_PLL_POSTDIV1_SHIFT;
447 	refdiv = (reg & RK3399_CRU_PLL_REFDIV_MASK) >>
448 	    RK3399_CRU_PLL_REFDIV_SHIFT;
449 	return 24000000ULL * fbdiv / refdiv / postdiv1 / postdiv2;
450 }
451 
452 int
453 rk3399_set_pll(struct rkclock_softc *sc, bus_size_t base, uint32_t freq)
454 {
455 	uint32_t fbdiv, postdiv1, postdiv2, refdiv;
456 
457 	/*
458 	 * It is not clear whether all combinations of the clock
459 	 * dividers result in a stable clock.  Therefore this function
460 	 * only supports a limited set of PLL clock rates.  For now
461 	 * this set covers all the CPU frequencies supported by the
462 	 * Linux kernel.
463 	 */
464 	switch (freq) {
465 	case 2208000000U:
466 	case 2184000000U:
467 	case 2088000000U:
468 	case 2040000000U:
469 	case 2016000000U:
470 	case 1992000000U:
471 	case 1896000000U:
472 	case 1800000000U:
473 	case 1704000000U:
474 	case 1608000000U:
475 	case 1512000000U:
476 	case 1488000000U:
477 	case 1416000000U:
478 	case 1200000000U:
479 		postdiv1 = postdiv2 = refdiv = 1;
480 		break;
481 	case 1008000000U:
482 	case 816000000U:
483 	case 696000000U:
484 		postdiv1 = 2; postdiv2 = refdiv = 1;
485 		break;
486 	case 600000000U:
487 		postdiv1 = 3; postdiv2 = refdiv = 1;
488 		break;
489 	case 408000000U:
490 		postdiv1 = postdiv2 = 2; refdiv = 1;
491 		break;
492 	case 216000000U:
493 		postdiv1 = 4; postdiv2 = 2; refdiv = 1;
494 		break;
495 	case 96000000U:
496 		postdiv1 = postdiv2 = 4; refdiv = 1;
497 		break;
498 	default:
499 		printf("%s: %d MHz\n", __func__, freq);
500 		return -1;
501 	}
502 
503 	/* Calculate feedback divider. */
504 	fbdiv = freq * postdiv1 * postdiv2 * refdiv / 24000000;
505 
506 	/*
507 	 * Select slow mode to guarantee a stable clock while we're
508 	 * adjusting the PLL.
509 	 */
510 	HWRITE4(sc, base + 0x000c,
511 	    RK3399_CRU_PLL_PLL_WORK_MODE_MASK << 16 |
512 	    RK3399_CRU_PLL_PLL_WORK_MODE_SLOW);
513 
514 	/* Set PLL rate. */
515 	HWRITE4(sc, base + 0x0000,
516 	    RK3399_CRU_PLL_FBDIV_MASK << 16 |
517 	    fbdiv << RK3399_CRU_PLL_FBDIV_SHIFT);
518 	HWRITE4(sc, base + 0x0004,
519 	    RK3399_CRU_PLL_POSTDIV2_MASK << 16 |
520 	    postdiv2 << RK3399_CRU_PLL_POSTDIV2_SHIFT |
521 	    RK3399_CRU_PLL_POSTDIV1_MASK << 16 |
522 	    postdiv1 << RK3399_CRU_PLL_POSTDIV1_SHIFT |
523 	    RK3399_CRU_PLL_REFDIV_MASK << 16 |
524 	    refdiv << RK3399_CRU_PLL_REFDIV_SHIFT);
525 
526 	/* Wait for PLL to stabilize. */
527 	while ((HREAD4(sc, base + 0x0008) & RK3399_CRU_PLL_PLL_LOCK) == 0)
528 		delay(10);
529 
530 	/* Switch back to normal mode. */
531 	HWRITE4(sc, base + 0x000c,
532 	    RK3399_CRU_PLL_PLL_WORK_MODE_MASK << 16 |
533 	    RK3399_CRU_PLL_PLL_WORK_MODE_NORMAL);
534 
535 	return 0;
536 }
537 
538 uint32_t
539 rk3399_armclk_parent(uint32_t mux)
540 {
541 	switch (mux) {
542 	case 0:
543 		return RK3399_PLL_ALPLL;
544 	case 1:
545 		return RK3399_PLL_ABPLL;
546 	case 2:
547 		return RK3399_PLL_DPLL;
548 	case 3:
549 		return RK3399_PLL_GPLL;
550 	}
551 
552 	return 0;
553 }
554 
555 uint32_t
556 rk3399_get_armclk(struct rkclock_softc *sc, bus_size_t clksel)
557 {
558 	uint32_t reg, mux, div_con;
559 	uint32_t idx;
560 
561 	reg = HREAD4(sc, clksel);
562 	mux = (reg & RK3399_CRU_CORE_PLL_SEL_MASK) >>
563 	    RK3399_CRU_CORE_PLL_SEL_SHIFT;
564 	div_con = (reg & RK3399_CRU_CLK_CORE_DIV_CON_MASK) >>
565 	    RK3399_CRU_CLK_CORE_DIV_CON_SHIFT;
566 	idx = rk3399_armclk_parent(mux);
567 
568 	return rk3399_get_frequency(sc, &idx) / (div_con + 1);
569 }
570 
571 int
572 rk3399_set_armclk(struct rkclock_softc *sc, bus_size_t clksel, uint32_t freq)
573 {
574 	uint32_t reg, mux;
575 	uint32_t old_freq, div;
576 	uint32_t idx;
577 
578 	old_freq = rk3399_get_armclk(sc, clksel);
579 	if (freq == old_freq)
580 		return 0;
581 
582 	reg = HREAD4(sc, clksel);
583 	mux = (reg & RK3399_CRU_CORE_PLL_SEL_MASK) >>
584 	    RK3399_CRU_CORE_PLL_SEL_SHIFT;
585 	idx = rk3399_armclk_parent(mux);
586 
587 	/* Keep the atclk_core and pclk_dbg clocks at or below 200 MHz. */
588 	div = 1;
589 	while (freq / (div + 1) > 200000000)
590 		div++;
591 
592 	/* When ramping up, set clock dividers first. */
593 	if (freq > old_freq) {
594 		HWRITE4(sc, RK3399_CRU_CLKSEL_CON(0),
595 		    RK3399_CRU_CLK_CORE_DIV_CON_MASK << 16 |
596 		    0 << RK3399_CRU_CLK_CORE_DIV_CON_SHIFT |
597 		    RK3399_CRU_ACLKM_CORE_DIV_CON_MASK << 16 |
598 		    1 << RK3399_CRU_ACLKM_CORE_DIV_CON_SHIFT);
599 		HWRITE4(sc, RK3399_CRU_CLKSEL_CON(1),
600 		    RK3399_CRU_PCLK_DBG_DIV_CON_MASK << 16 |
601 		    div << RK3399_CRU_PCLK_DBG_DIV_CON_SHIFT |
602 		    RK3399_CRU_ATCLK_CORE_DIV_CON_MASK << 16 |
603 		    div << RK3399_CRU_ATCLK_CORE_DIV_CON_SHIFT);
604 	}
605 
606 	rk3399_set_frequency(sc, &idx, freq);
607 
608 	/* When ramping dowm, set clock dividers last. */
609 	if (freq < old_freq) {
610 		HWRITE4(sc, RK3399_CRU_CLKSEL_CON(0),
611 		    RK3399_CRU_CLK_CORE_DIV_CON_MASK << 16 |
612 		    0 << RK3399_CRU_CLK_CORE_DIV_CON_SHIFT |
613 		    RK3399_CRU_ACLKM_CORE_DIV_CON_MASK << 16 |
614 		    1 << RK3399_CRU_ACLKM_CORE_DIV_CON_SHIFT);
615 		HWRITE4(sc, RK3399_CRU_CLKSEL_CON(1),
616 		    RK3399_CRU_PCLK_DBG_DIV_CON_MASK << 16 |
617 		    div << RK3399_CRU_PCLK_DBG_DIV_CON_SHIFT |
618 		    RK3399_CRU_ATCLK_CORE_DIV_CON_MASK << 16 |
619 		    div << RK3399_CRU_ATCLK_CORE_DIV_CON_SHIFT);
620 	}
621 
622 	return 0;
623 }
624 
625 uint32_t
626 rk3399_get_i2c(struct rkclock_softc *sc, size_t base, int shift)
627 {
628 	uint32_t reg, mux, div_con;
629 	uint32_t idx, freq;
630 
631 	reg = HREAD4(sc, base);
632 	mux = (reg >> (7 + shift)) & 0x1;
633 	div_con = (reg >> shift) & 0x7f;
634 	if (mux == 1) {
635 		idx = RK3399_PLL_PPLL;
636 		freq = rk3399_pmu_get_frequency(rk3399_pmucru_sc, &idx);
637 	} else {
638 		idx = RK3399_PLL_CPLL;
639 		freq = rk3399_get_frequency(sc, &idx);
640 	}
641 
642 	return freq / (div_con + 1);
643 }
644 
645 uint32_t
646 rk3399_get_frequency(void *cookie, uint32_t *cells)
647 {
648 	struct rkclock_softc *sc = cookie;
649 	uint32_t idx = cells[0];
650 	uint32_t reg, mux, div_con;
651 
652 	switch (idx) {
653 	case RK3399_PLL_ALPLL:
654 		return rk3399_get_pll(sc, RK3399_CRU_LPLL_CON(0));
655 	case RK3399_PLL_ABPLL:
656 		return rk3399_get_pll(sc, RK3399_CRU_BPLL_CON(0));
657 	case RK3399_PLL_DPLL:
658 		return rk3399_get_pll(sc, RK3399_CRU_DPLL_CON(0));
659 	case RK3399_PLL_CPLL:
660 		return rk3399_get_pll(sc, RK3399_CRU_CPLL_CON(0));
661 	case RK3399_PLL_GPLL:
662 		return rk3399_get_pll(sc, RK3399_CRU_GPLL_CON(0));
663 	case RK3399_PLL_NPLL:
664 		return rk3399_get_pll(sc, RK3399_CRU_NPLL_CON(0));
665 	case RK3399_ARMCLKL:
666 		return rk3399_get_armclk(sc, RK3399_CRU_CLKSEL_CON(0));
667 	case RK3399_ARMCLKB:
668 		return rk3399_get_armclk(sc, RK3399_CRU_CLKSEL_CON(2));
669 	case RK3399_CLK_I2C1:
670 		return rk3399_get_i2c(sc, RK3399_CRU_CLKSEL_CON(61), 0);
671 	case RK3399_CLK_I2C2:
672 		return rk3399_get_i2c(sc, RK3399_CRU_CLKSEL_CON(62), 0);
673 	case RK3399_CLK_I2C3:
674 		return rk3399_get_i2c(sc, RK3399_CRU_CLKSEL_CON(63), 0);
675 	case RK3399_CLK_I2C5:
676 		return rk3399_get_i2c(sc, RK3399_CRU_CLKSEL_CON(61), 8);
677 	case RK3399_CLK_I2C6:
678 		return rk3399_get_i2c(sc, RK3399_CRU_CLKSEL_CON(61), 8);
679 	case RK3399_CLK_I2C7:
680 		return rk3399_get_i2c(sc, RK3399_CRU_CLKSEL_CON(61), 8);
681 	case RK3399_CLK_SDMMC:
682 		reg = HREAD4(sc, RK3399_CRU_CLKSEL_CON(16));
683 		mux = (reg >> 8) & 0x7;
684 		div_con = reg & 0x7f;
685 		switch (mux) {
686 		case 0:
687 			idx = RK3399_PLL_CPLL;
688 			break;
689 		case 1:
690 			idx = RK3399_PLL_GPLL;
691 			break;
692 		case 2:
693 			idx = RK3399_PLL_NPLL;
694 			break;
695 #ifdef notyet
696 		case 3:
697 			idx = RK3399_PLL_PPLL;
698 			break;
699 		case 4:
700 			idx = RK3399_USB_480M;
701 			break;
702 #endif
703 		case 5:
704 			return 24000000 / (div_con + 1);
705 		default:
706 			return 0;
707 		}
708 		return rk3399_get_frequency(sc, &idx) / (div_con + 1);
709 		break;
710 	case RK3399_CLK_UART0:
711 		reg = HREAD4(sc, RK3399_CRU_CLKSEL_CON(33));
712 		mux = (reg >> 8) & 0x3;
713 		div_con = reg & 0x7f;
714 		if (mux == 2)
715 			return 24000000 / (div_con + 1);
716 		break;
717 	case RK3399_CLK_UART1:
718 		reg = HREAD4(sc, RK3399_CRU_CLKSEL_CON(34));
719 		mux = (reg >> 8) & 0x3;
720 		div_con = reg & 0x7f;
721 		if (mux == 2)
722 			return 24000000 / (div_con + 1);
723 		break;
724 	case RK3399_CLK_UART2:
725 		reg = HREAD4(sc, RK3399_CRU_CLKSEL_CON(35));
726 		mux = (reg >> 8) & 0x3;
727 		div_con = reg & 0x7f;
728 		if (mux == 2)
729 			return 24000000 / (div_con + 1);
730 		break;
731 	case RK3399_CLK_UART3:
732 		reg = HREAD4(sc, RK3399_CRU_CLKSEL_CON(36));
733 		mux = (reg >> 8) & 0x3;
734 		div_con = reg & 0x7f;
735 		if (mux == 2)
736 			return 24000000 / (div_con + 1);
737 		break;
738 	case RK3399_HCLK_SDMMC:
739 		reg = HREAD4(sc, RK3399_CRU_CLKSEL_CON(13));
740 		mux = (reg >> 15) & 0x1;
741 		div_con = (reg >> 8) & 0x1f;
742 		idx = mux ? RK3399_PLL_CPLL : RK3399_PLL_GPLL;
743 		return rk3399_get_frequency(sc, &idx) / (div_con + 1);
744 	default:
745 		break;
746 	}
747 
748 	printf("%s: 0x%08x\n", __func__, idx);
749 	return 0;
750 }
751 
752 int
753 rk3399_set_frequency(void *cookie, uint32_t *cells, uint32_t freq)
754 {
755 	struct rkclock_softc *sc = cookie;
756 	uint32_t idx = cells[0];
757 
758 	switch (idx) {
759 	case RK3399_PLL_ALPLL:
760 		return rk3399_set_pll(sc, RK3399_CRU_LPLL_CON(0), freq);
761 	case RK3399_PLL_ABPLL:
762 		return rk3399_set_pll(sc, RK3399_CRU_BPLL_CON(0), freq);
763 	case RK3399_ARMCLKL:
764 		return rk3399_set_armclk(sc, RK3399_CRU_CLKSEL_CON(0), freq);
765 	case RK3399_ARMCLKB:
766 		return rk3399_set_armclk(sc, RK3399_CRU_CLKSEL_CON(2), freq);
767 	}
768 
769 	printf("%s: 0x%08x\n", __func__, idx);
770 	return -1;
771 }
772 
773 void
774 rk3399_enable(void *cookie, uint32_t *cells, int on)
775 {
776 	uint32_t idx = cells[0];
777 
778 	switch (idx) {
779 	case RK3399_CLK_I2C1:
780 	case RK3399_CLK_I2C2:
781 	case RK3399_CLK_I2C3:
782 	case RK3399_CLK_I2C5:
783 	case RK3399_CLK_I2C6:
784 	case RK3399_CLK_I2C7:
785 	case RK3399_CLK_SDMMC:
786 	case RK3399_CLK_EMMC:
787 	case RK3399_CLK_TSADC:
788 	case RK3399_CLK_UART0:
789 	case RK3399_CLK_UART1:
790 	case RK3399_CLK_UART2:
791 	case RK3399_CLK_UART3:
792 	case RK3399_CLK_MAC_RX:
793 	case RK3399_CLK_MAC_TX:
794 	case RK3399_CLK_MAC:
795 	case RK3399_CLK_USB3OTG0_REF:
796 	case RK3399_CLK_USB3OTG1_REF:
797 	case RK3399_CLK_USB3OTG0_SUSPEND:
798 	case RK3399_CLK_USB3OTG1_SUSPEND:
799 	case RK3399_CLK_SDMMC_DRV:
800 	case RK3399_CLK_SDMMC_SAMPLE:
801 	case RK3399_ACLK_EMMC:
802 	case RK3399_ACLK_GMAC:
803 	case RK3399_ACLK_USB3OTG0:
804 	case RK3399_ACLK_USB3OTG1:
805 	case RK3399_ACLK_USB3_GRF:
806 	case RK3399_PCLK_I2C1:
807 	case RK3399_PCLK_I2C2:
808 	case RK3399_PCLK_I2C3:
809 	case RK3399_PCLK_I2C5:
810 	case RK3399_PCLK_I2C6:
811 	case RK3399_PCLK_I2C7:
812 	case RK3399_PCLK_TSADC:
813 	case RK3399_PCLK_GMAC:
814 	case RK3399_HCLK_HOST0:
815 	case RK3399_HCLK_HOST0_ARB:
816 	case RK3399_HCLK_HOST1:
817 	case RK3399_HCLK_HOST1_ARB:
818 	case RK3399_HCLK_SDMMC:
819 		/* Enabled by default. */
820 		break;
821 	default:
822 		printf("%s: 0x%08x\n", __func__, idx);
823 		break;
824 	}
825 }
826 
827 void
828 rk3399_reset(void *cookie, uint32_t *cells, int on)
829 {
830 	struct rkclock_softc *sc = cookie;
831 	uint32_t idx = cells[0];
832 	uint32_t mask = (1 << (idx % 16));
833 
834 	HWRITE4(sc, RK3399_CRU_SOFTRST_CON(idx / 16),
835 	    mask << 16 | (on ? mask : 0));
836 }
837 
838 int
839 rk3399_cpuspeed(int *freq)
840 {
841 	uint32_t idx = RK3399_ARMCLKL;
842 
843 	*freq = rk3399_get_frequency(rkclock_cpuspeed_sc, &idx) / 1000000;
844 	return 0;
845 }
846 
847 /* PMUCRU */
848 
849 void
850 rk3399_pmu_init(struct rkclock_softc *sc)
851 {
852 	rk3399_pmucru_sc = sc;
853 }
854 
855 uint32_t
856 rk3399_pmu_get_i2c(struct rkclock_softc *sc, size_t base, int shift)
857 {
858 	uint32_t reg, div_con;
859 	uint32_t idx;
860 
861 	reg = HREAD4(sc, base);
862 	div_con = (reg >> shift) & 0x7f;
863 	idx = RK3399_PLL_PPLL;
864 	return rk3399_get_frequency(sc, &idx) / (div_con + 1);
865 }
866 
867 uint32_t
868 rk3399_pmu_get_frequency(void *cookie, uint32_t *cells)
869 {
870 	struct rkclock_softc *sc = cookie;
871 	uint32_t idx = cells[0];
872 
873 	switch (idx) {
874 	case RK3399_PLL_PPLL:
875 		return rk3399_get_pll(sc, RK3399_PMUCRU_PPLL_CON(0));
876 	case RK3399_CLK_I2C0:
877 		return rk3399_pmu_get_i2c(sc, RK3399_PMUCRU_CLKSEL_CON(2), 0);
878 	case RK3399_CLK_I2C4:
879 		return rk3399_pmu_get_i2c(sc, RK3399_PMUCRU_CLKSEL_CON(3), 0);
880 	case RK3399_CLK_I2C8:
881 		return rk3399_pmu_get_i2c(sc, RK3399_PMUCRU_CLKSEL_CON(2), 8);
882 	default:
883 		break;
884 	}
885 
886 	printf("%s: 0x%08x\n", __func__, idx);
887 	return 0;
888 }
889 
890 int
891 rk3399_pmu_set_frequency(void *cookie, uint32_t *cells, uint32_t freq)
892 {
893 	uint32_t idx = cells[0];
894 
895 	printf("%s: 0x%08x\n", __func__, idx);
896 	return -1;
897 }
898 
899 void
900 rk3399_pmu_enable(void *cookie, uint32_t *cells, int on)
901 {
902 	uint32_t idx = cells[0];
903 
904 	switch (idx) {
905 	case RK3399_CLK_I2C0:
906 	case RK3399_CLK_I2C4:
907 	case RK3399_CLK_I2C8:
908 	case RK3399_PCLK_I2C0:
909 	case RK3399_PCLK_I2C4:
910 	case RK3399_PCLK_I2C8:
911 		/* Enabled by default. */
912 		break;
913 	default:
914 		printf("%s: 0x%08x\n", __func__, idx);
915 		break;
916 	}
917 }
918 
919 void
920 rk3399_pmu_reset(void *cookie, uint32_t *cells, int on)
921 {
922 	uint32_t idx = cells[0];
923 
924 	printf("%s: 0x%08x\n", __func__, idx);
925 }
926