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