1 /* $OpenBSD: rkclock.c,v 1.55 2021/04/07 16:35:02 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 #include "rkclock_clocks.h" 174 175 struct rkclock { 176 uint16_t idx; 177 uint16_t reg; 178 uint16_t sel_mask; 179 uint16_t div_mask; 180 uint16_t parents[8]; 181 uint32_t flags; 182 }; 183 184 #define SEL(l, f) (((1 << (l - f + 1)) - 1) << f) 185 #define DIV(l, f) SEL(l, f) 186 187 #define FIXED_PARENT (1 << 0) 188 #define SET_PARENT (1 << 1) 189 190 #define HREAD4(sc, reg) \ 191 (bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg))) 192 #define HWRITE4(sc, reg, val) \ 193 bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val)) 194 #define HSET4(sc, reg, bits) \ 195 HWRITE4((sc), (reg), HREAD4((sc), (reg)) | (bits)) 196 #define HCLR4(sc, reg, bits) \ 197 HWRITE4((sc), (reg), HREAD4((sc), (reg)) & ~(bits)) 198 199 struct rkclock_softc { 200 struct device sc_dev; 201 bus_space_tag_t sc_iot; 202 bus_space_handle_t sc_ioh; 203 struct regmap *sc_grf; 204 205 uint32_t sc_phandle; 206 struct rkclock *sc_clocks; 207 208 struct clock_device sc_cd; 209 struct reset_device sc_rd; 210 }; 211 212 int rkclock_match(struct device *, void *, void *); 213 void rkclock_attach(struct device *, struct device *, void *); 214 215 struct cfattach rkclock_ca = { 216 sizeof (struct rkclock_softc), rkclock_match, rkclock_attach 217 }; 218 219 struct cfdriver rkclock_cd = { 220 NULL, "rkclock", DV_DULL 221 }; 222 223 void rk3288_init(struct rkclock_softc *); 224 uint32_t rk3288_get_frequency(void *, uint32_t *); 225 int rk3288_set_frequency(void *, uint32_t *, uint32_t); 226 void rk3288_enable(void *, uint32_t *, int); 227 void rk3288_reset(void *, uint32_t *, int); 228 229 void rk3308_init(struct rkclock_softc *); 230 uint32_t rk3308_get_frequency(void *, uint32_t *); 231 int rk3308_set_frequency(void *, uint32_t *, uint32_t); 232 int rk3308_set_parent(void *, uint32_t *, uint32_t *); 233 void rk3308_enable(void *, uint32_t *, int); 234 void rk3308_reset(void *, uint32_t *, int); 235 236 void rk3328_init(struct rkclock_softc *); 237 uint32_t rk3328_get_frequency(void *, uint32_t *); 238 int rk3328_set_frequency(void *, uint32_t *, uint32_t); 239 int rk3328_set_parent(void *, uint32_t *, uint32_t *); 240 void rk3328_enable(void *, uint32_t *, int); 241 void rk3328_reset(void *, uint32_t *, int); 242 243 void rk3399_init(struct rkclock_softc *); 244 uint32_t rk3399_get_frequency(void *, uint32_t *); 245 int rk3399_set_frequency(void *, uint32_t *, uint32_t); 246 void rk3399_enable(void *, uint32_t *, int); 247 void rk3399_reset(void *, uint32_t *, int); 248 249 void rk3399_pmu_init(struct rkclock_softc *); 250 uint32_t rk3399_pmu_get_frequency(void *, uint32_t *); 251 int rk3399_pmu_set_frequency(void *, uint32_t *, uint32_t); 252 void rk3399_pmu_enable(void *, uint32_t *, int); 253 void rk3399_pmu_reset(void *, uint32_t *, int); 254 255 struct rkclock_compat { 256 const char *compat; 257 int assign; 258 void (*init)(struct rkclock_softc *); 259 void (*enable)(void *, uint32_t *, int); 260 uint32_t (*get_frequency)(void *, uint32_t *); 261 int (*set_frequency)(void *, uint32_t *, uint32_t); 262 int (*set_parent)(void *, uint32_t *, uint32_t *); 263 void (*reset)(void *, uint32_t *, int); 264 }; 265 266 struct rkclock_compat rkclock_compat[] = { 267 { 268 "rockchip,rk3288-cru", 0, rk3288_init, 269 rk3288_enable, rk3288_get_frequency, 270 rk3288_set_frequency, NULL, 271 rk3288_reset 272 }, 273 { 274 "rockchip,rk3308-cru", 1, rk3308_init, 275 rk3308_enable, rk3308_get_frequency, 276 rk3308_set_frequency, rk3308_set_parent, 277 rk3308_reset 278 }, 279 { 280 "rockchip,rk3328-cru", 1, rk3328_init, 281 rk3328_enable, rk3328_get_frequency, 282 rk3328_set_frequency, rk3328_set_parent, 283 rk3328_reset 284 }, 285 { 286 "rockchip,rk3399-cru", 1, rk3399_init, 287 rk3399_enable, rk3399_get_frequency, 288 rk3399_set_frequency, NULL, 289 rk3399_reset 290 }, 291 { 292 "rockchip,rk3399-pmucru", 1, rk3399_pmu_init, 293 rk3399_pmu_enable, rk3399_pmu_get_frequency, 294 rk3399_pmu_set_frequency, NULL, 295 rk3399_pmu_reset 296 } 297 }; 298 299 int 300 rkclock_match(struct device *parent, void *match, void *aux) 301 { 302 struct fdt_attach_args *faa = aux; 303 int i; 304 305 for (i = 0; i < nitems(rkclock_compat); i++) { 306 if (OF_is_compatible(faa->fa_node, rkclock_compat[i].compat)) 307 return 10; 308 } 309 310 return 0; 311 } 312 313 void 314 rkclock_attach(struct device *parent, struct device *self, void *aux) 315 { 316 struct rkclock_softc *sc = (struct rkclock_softc *)self; 317 struct fdt_attach_args *faa = aux; 318 uint32_t grf; 319 int i; 320 321 if (faa->fa_nreg < 1) { 322 printf(": no registers\n"); 323 return; 324 } 325 326 sc->sc_iot = faa->fa_iot; 327 if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr, 328 faa->fa_reg[0].size, 0, &sc->sc_ioh)) { 329 printf(": can't map registers\n"); 330 return; 331 } 332 333 grf = OF_getpropint(faa->fa_node, "rockchip,grf", 0); 334 sc->sc_grf = regmap_byphandle(grf); 335 336 printf("\n"); 337 338 sc->sc_phandle = OF_getpropint(faa->fa_node, "phandle", 0); 339 340 for (i = 0; i < nitems(rkclock_compat); i++) { 341 if (OF_is_compatible(faa->fa_node, rkclock_compat[i].compat)) { 342 break; 343 } 344 } 345 KASSERT(i < nitems(rkclock_compat)); 346 347 if (rkclock_compat[i].init) 348 rkclock_compat[i].init(sc); 349 350 sc->sc_cd.cd_node = faa->fa_node; 351 sc->sc_cd.cd_cookie = sc; 352 sc->sc_cd.cd_enable = rkclock_compat[i].enable; 353 sc->sc_cd.cd_get_frequency = rkclock_compat[i].get_frequency; 354 sc->sc_cd.cd_set_frequency = rkclock_compat[i].set_frequency; 355 sc->sc_cd.cd_set_parent = rkclock_compat[i].set_parent; 356 clock_register(&sc->sc_cd); 357 358 sc->sc_rd.rd_node = faa->fa_node; 359 sc->sc_rd.rd_cookie = sc; 360 sc->sc_rd.rd_reset = rkclock_compat[i].reset; 361 reset_register(&sc->sc_rd); 362 363 if (rkclock_compat[i].assign) 364 clock_set_assigned(faa->fa_node); 365 } 366 367 struct rkclock * 368 rkclock_lookup(struct rkclock_softc *sc, uint32_t idx) 369 { 370 struct rkclock *clk; 371 372 for (clk = sc->sc_clocks; clk->idx; clk++) { 373 if (clk->idx == idx) 374 return clk; 375 } 376 377 return NULL; 378 } 379 380 uint32_t 381 rkclock_div_con(struct rkclock_softc *sc, struct rkclock *clk, 382 uint32_t mux, uint32_t freq) 383 { 384 uint32_t parent_freq, div, div_con, max_div_con; 385 uint32_t idx = clk->parents[mux]; 386 387 /* Derive maximum value from mask. */ 388 max_div_con = clk->div_mask >> (ffs(clk->div_mask) - 1); 389 390 parent_freq = sc->sc_cd.cd_get_frequency(sc, &idx); 391 div = (parent_freq + freq - 1) / freq; 392 div_con = (div > 0 ? div - 1 : 0); 393 return (div_con < max_div_con) ? div_con : max_div_con; 394 } 395 396 uint32_t 397 rkclock_freq(struct rkclock_softc *sc, struct rkclock *clk, 398 uint32_t mux, uint32_t freq) 399 { 400 uint32_t parent_freq, div_con; 401 uint32_t idx = clk->parents[mux]; 402 403 parent_freq = sc->sc_cd.cd_get_frequency(sc, &idx); 404 div_con = rkclock_div_con(sc, clk, mux, freq); 405 return parent_freq / (div_con + 1); 406 } 407 408 uint32_t 409 rkclock_get_frequency(struct rkclock_softc *sc, uint32_t idx) 410 { 411 struct rkclock *clk; 412 uint32_t reg, mux, div_con; 413 int shift; 414 415 clk = rkclock_lookup(sc, idx); 416 if (clk == NULL) { 417 printf("%s: 0x%08x\n", __func__, idx); 418 return 0; 419 } 420 421 reg = HREAD4(sc, clk->reg); 422 shift = ffs(clk->sel_mask) - 1; 423 if (shift == -1) 424 mux = 0; 425 else 426 mux = (reg & clk->sel_mask) >> shift; 427 shift = ffs(clk->div_mask) - 1; 428 if (shift == -1) 429 div_con = 0; 430 else 431 div_con = (reg & clk->div_mask) >> shift; 432 433 if (clk->parents[mux] == 0) { 434 printf("%s: parent 0x%08x\n", __func__, idx); 435 return 0; 436 } 437 idx = clk->parents[mux]; 438 return sc->sc_cd.cd_get_frequency(sc, &idx) / (div_con + 1); 439 } 440 441 int 442 rkclock_set_frequency(struct rkclock_softc *sc, uint32_t idx, uint32_t freq) 443 { 444 struct rkclock *clk; 445 uint32_t reg, mux, div_con; 446 uint32_t best_freq, best_mux, f; 447 int sel_shift, div_shift, i; 448 449 clk = rkclock_lookup(sc, idx); 450 if (clk == NULL) { 451 printf("%s: 0x%08x\n", __func__, idx); 452 return -1; 453 } 454 455 reg = HREAD4(sc, clk->reg); 456 sel_shift = ffs(clk->sel_mask) - 1; 457 if (sel_shift == -1) 458 mux = sel_shift = 0; 459 else 460 mux = (reg & clk->sel_mask) >> sel_shift; 461 462 if (clk->parents[mux] == 0) { 463 printf("%s: parent 0x%08x\n", __func__, idx); 464 return 0; 465 } 466 467 if (clk->flags & SET_PARENT) { 468 idx = clk->parents[mux]; 469 sc->sc_cd.cd_set_frequency(sc, &idx, freq); 470 if (clk->div_mask == 0) 471 return 0; 472 } 473 474 if (clk->div_mask == 0) { 475 printf("%s: 0x%08x\n", __func__, idx); 476 return -1; 477 } 478 479 /* 480 * Start out with the current parent. This prevents 481 * unecessary switching to a different parent. 482 */ 483 best_freq = rkclock_freq(sc, clk, mux, freq); 484 best_mux = mux; 485 486 /* 487 * Find the parent that allows configuration of a frequency 488 * closest to the target frequency. 489 */ 490 if ((clk->flags & FIXED_PARENT) == 0) { 491 for (i = 0; i < nitems(clk->parents); i++) { 492 if (clk->parents[i] == 0) 493 continue; 494 f = rkclock_freq(sc, clk, i, freq); 495 if ((f > best_freq && f <= freq) || 496 (f < best_freq && f >= freq)) { 497 best_freq = f; 498 best_mux = i; 499 } 500 } 501 } 502 503 div_con = rkclock_div_con(sc, clk, best_mux, freq); 504 div_shift = ffs(clk->div_mask) - 1; 505 HWRITE4(sc, clk->reg, 506 clk->sel_mask << 16 | best_mux << sel_shift | 507 clk->div_mask << 16 | div_con << div_shift); 508 return 0; 509 } 510 511 int 512 rkclock_set_parent(struct rkclock_softc *sc, uint32_t idx, uint32_t parent) 513 { 514 struct rkclock *clk; 515 uint32_t mux; 516 int shift; 517 518 clk = rkclock_lookup(sc, idx); 519 if (clk == NULL || clk->sel_mask == 0) { 520 printf("%s: 0x%08x\n", __func__, idx); 521 return -1; 522 } 523 524 for (mux = 0; mux < nitems(clk->parents); mux++) { 525 if (clk->parents[mux] == parent) 526 break; 527 } 528 if (mux == nitems(clk->parents) || parent == 0) { 529 printf("%s: 0x%08x parent 0x%08x\n", __func__, idx, parent); 530 return -1; 531 } 532 533 shift = ffs(clk->sel_mask) - 1; 534 HWRITE4(sc, clk->reg, clk->sel_mask << 16 | mux << shift); 535 return 0; 536 } 537 538 /* 539 * Rockchip RK3288 540 */ 541 542 struct rkclock rk3288_clocks[] = { 543 { 544 RK3288_CLK_SDMMC, RK3288_CRU_CLKSEL_CON(11), 545 SEL(7, 6), DIV(5, 0), 546 { RK3288_PLL_CPLL, RK3288_PLL_GPLL, RK3288_XIN24M } 547 } 548 }; 549 550 void 551 rk3288_init(struct rkclock_softc *sc) 552 { 553 int node; 554 555 /* 556 * Since the hardware comes up with a really conservative CPU 557 * clock frequency, and U-Boot doesn't set it to a more 558 * reasonable default, try to do so here. These defaults were 559 * chosen assuming that the CPU voltage is at least 1.1 V. 560 * Only do this on the Tinker-RK3288 for now where this is 561 * likely to be true given the default voltages for the 562 * regulators on that board. 563 */ 564 node = OF_finddevice("/"); 565 if (OF_is_compatible(node, "rockchip,rk3288-tinker")) { 566 uint32_t idx; 567 568 /* Run at 1.2 GHz. */ 569 idx = RK3288_ARMCLK; 570 rk3288_set_frequency(sc, &idx, 1200000000); 571 } 572 573 sc->sc_clocks = rk3288_clocks; 574 } 575 576 uint32_t 577 rk3288_get_pll(struct rkclock_softc *sc, bus_size_t base) 578 { 579 uint32_t clkod, clkr, clkf; 580 uint32_t reg; 581 582 reg = HREAD4(sc, base); 583 clkod = (reg & RK3288_CRU_PLL_CLKOD_MASK) >> 584 RK3288_CRU_PLL_CLKOD_SHIFT; 585 clkr = (reg & RK3288_CRU_PLL_CLKR_MASK) >> 586 RK3288_CRU_PLL_CLKR_SHIFT; 587 reg = HREAD4(sc, base + 4); 588 clkf = (reg & RK3288_CRU_PLL_CLKF_MASK) >> 589 RK3288_CRU_PLL_CLKF_SHIFT; 590 return 24000000ULL * (clkf + 1) / (clkr + 1) / (clkod + 1); 591 } 592 593 int 594 rk3288_set_pll(struct rkclock_softc *sc, bus_size_t base, uint32_t freq) 595 { 596 int shift = 4 * (base / RK3288_CRU_CPLL_CON(0)); 597 uint32_t no, nr, nf; 598 599 /* 600 * It is not clear whether all combinations of the clock 601 * dividers result in a stable clock. Therefore this function 602 * only supports a limited set of PLL clock rates. For now 603 * this set covers all the CPU frequencies supported by the 604 * Linux kernel. 605 */ 606 switch (freq) { 607 case 1800000000: 608 case 1704000000: 609 case 1608000000: 610 case 1512000000: 611 case 1488000000: 612 case 1416000000: 613 case 1200000000: 614 nr = no = 1; 615 break; 616 case 1008000000: 617 case 816000000: 618 case 696000000: 619 case 600000000: 620 nr = 1; no = 2; 621 break; 622 case 408000000: 623 case 312000000: 624 nr = 1; no = 4; 625 break; 626 case 216000000: 627 case 126000000: 628 nr = 1; no = 8; 629 break; 630 default: 631 printf("%s: %u Hz\n", __func__, freq); 632 return -1; 633 } 634 635 /* Calculate feedback divider. */ 636 nf = freq * nr * no / 24000000; 637 638 /* 639 * Select slow mode to guarantee a stable clock while we're 640 * adjusting the PLL. 641 */ 642 HWRITE4(sc, RK3288_CRU_MODE_CON, 643 (RK3288_CRU_MODE_PLL_WORK_MODE_MASK << 16 | 644 RK3288_CRU_MODE_PLL_WORK_MODE_SLOW) << shift); 645 646 /* Assert reset. */ 647 HWRITE4(sc, base + 0x000c, 648 RK3288_CRU_PLL_RESET << 16 | RK3288_CRU_PLL_RESET); 649 650 /* Set PLL rate. */ 651 HWRITE4(sc, base + 0x0000, 652 RK3288_CRU_PLL_CLKR_MASK << 16 | 653 (nr - 1) << RK3288_CRU_PLL_CLKR_SHIFT | 654 RK3288_CRU_PLL_CLKOD_MASK << 16 | 655 (no - 1) << RK3288_CRU_PLL_CLKOD_SHIFT); 656 HWRITE4(sc, base + 0x0004, 657 RK3288_CRU_PLL_CLKF_MASK << 16 | 658 (nf - 1) << RK3288_CRU_PLL_CLKF_SHIFT); 659 660 /* Deassert reset and wait. */ 661 HWRITE4(sc, base + 0x000c, 662 RK3288_CRU_PLL_RESET << 16); 663 delay((nr * 500 / 24) + 1); 664 665 /* Switch back to normal mode. */ 666 HWRITE4(sc, RK3288_CRU_MODE_CON, 667 (RK3288_CRU_MODE_PLL_WORK_MODE_MASK << 16 | 668 RK3288_CRU_MODE_PLL_WORK_MODE_NORMAL) << shift); 669 670 return 0; 671 } 672 673 uint32_t 674 rk3288_get_frequency(void *cookie, uint32_t *cells) 675 { 676 struct rkclock_softc *sc = cookie; 677 uint32_t idx = cells[0]; 678 uint32_t reg, mux, div_con, aclk_div_con; 679 680 switch (idx) { 681 case RK3288_PLL_APLL: 682 return rk3288_get_pll(sc, RK3288_CRU_APLL_CON(0)); 683 case RK3288_PLL_CPLL: 684 return rk3288_get_pll(sc, RK3288_CRU_CPLL_CON(0)); 685 case RK3288_PLL_GPLL: 686 return rk3288_get_pll(sc, RK3288_CRU_GPLL_CON(0)); 687 case RK3288_PLL_NPLL: 688 return rk3288_get_pll(sc, RK3288_CRU_NPLL_CON(0)); 689 case RK3288_ARMCLK: 690 reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(0)); 691 mux = (reg >> 15) & 0x1; 692 div_con = (reg >> 8) & 0x1f; 693 idx = (mux == 0) ? RK3288_PLL_APLL : RK3288_PLL_GPLL; 694 return rk3288_get_frequency(sc, &idx) / (div_con + 1); 695 case RK3288_XIN24M: 696 return 24000000; 697 case RK3288_CLK_UART0: 698 reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(13)); 699 mux = (reg >> 8) & 0x3; 700 div_con = reg & 0x7f; 701 if (mux == 2) 702 return 24000000 / (div_con + 1); 703 break; 704 case RK3288_CLK_UART1: 705 reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(14)); 706 mux = (reg >> 8) & 0x3; 707 div_con = reg & 0x7f; 708 if (mux == 2) 709 return 24000000 / (div_con + 1); 710 break; 711 case RK3288_CLK_UART2: 712 reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(15)); 713 mux = (reg >> 8) & 0x3; 714 div_con = reg & 0x7f; 715 if (mux == 2) 716 return 24000000 / (div_con + 1); 717 break; 718 case RK3288_CLK_UART3: 719 reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(16)); 720 mux = (reg >> 8) & 0x3; 721 div_con = reg & 0x7f; 722 if (mux == 2) 723 return 24000000 / (div_con + 1); 724 break; 725 case RK3288_CLK_UART4: 726 reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(3)); 727 mux = (reg >> 8) & 0x3; 728 div_con = reg & 0x7f; 729 if (mux == 2) 730 return 24000000 / (div_con + 1); 731 break; 732 case RK3288_CLK_MAC: 733 reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(21)); 734 if (reg & 0x10) 735 return 125000000; 736 mux = (reg >> 0) & 0x3; 737 div_con = (reg >> 8) & 0x1f; 738 switch (mux) { 739 case 0: 740 idx = RK3288_PLL_NPLL; 741 break; 742 case 1: 743 idx = RK3288_PLL_CPLL; 744 break; 745 case 2: 746 idx = RK3288_PLL_GPLL; 747 break; 748 default: 749 return 0; 750 } 751 return rk3288_get_frequency(sc, &idx) / (div_con + 1); 752 case RK3288_PCLK_I2C0: 753 case RK3288_PCLK_I2C2: 754 reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(1)); 755 mux = (reg >> 15) & 0x1; 756 /* pd_bus_pclk_div_con */ 757 div_con = (reg >> 12) & 0x7; 758 if (mux == 1) 759 idx = RK3288_PLL_GPLL; 760 else 761 idx = RK3288_PLL_CPLL; 762 return rk3288_get_frequency(sc, &idx) / (div_con + 1); 763 case RK3288_PCLK_I2C1: 764 case RK3288_PCLK_I2C3: 765 case RK3288_PCLK_I2C4: 766 case RK3288_PCLK_I2C5: 767 reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(10)); 768 mux = (reg >> 15) & 0x1; 769 /* peri_pclk_div_con */ 770 div_con = (reg >> 12) & 0x3; 771 /* peri_aclk_div_con */ 772 aclk_div_con = reg & 0xf; 773 if (mux == 1) 774 idx = RK3288_PLL_GPLL; 775 else 776 idx = RK3288_PLL_CPLL; 777 return (rk3288_get_frequency(sc, &idx) / (aclk_div_con + 1)) >> 778 div_con; 779 default: 780 break; 781 } 782 783 return rkclock_get_frequency(sc, idx); 784 } 785 786 int 787 rk3288_set_frequency(void *cookie, uint32_t *cells, uint32_t freq) 788 { 789 struct rkclock_softc *sc = cookie; 790 uint32_t idx = cells[0]; 791 int error; 792 793 switch (idx) { 794 case RK3288_PLL_APLL: 795 return rk3288_set_pll(sc, RK3288_CRU_APLL_CON(0), freq); 796 case RK3288_ARMCLK: 797 idx = RK3288_PLL_APLL; 798 error = rk3288_set_frequency(sc, &idx, freq); 799 if (error == 0) { 800 HWRITE4(sc, RK3288_CRU_CLKSEL_CON(0), 801 ((1 << 15) | (0x1f << 8)) << 16); 802 } 803 return error; 804 default: 805 break; 806 } 807 808 return rkclock_set_frequency(sc, idx, freq); 809 } 810 811 void 812 rk3288_enable(void *cookie, uint32_t *cells, int on) 813 { 814 uint32_t idx = cells[0]; 815 816 switch (idx) { 817 case RK3288_CLK_SDMMC: 818 case RK3288_CLK_TSADC: 819 case RK3288_CLK_UART0: 820 case RK3288_CLK_UART1: 821 case RK3288_CLK_UART2: 822 case RK3288_CLK_UART3: 823 case RK3288_CLK_UART4: 824 case RK3288_CLK_MAC_RX: 825 case RK3288_CLK_MAC_TX: 826 case RK3288_CLK_SDMMC_DRV: 827 case RK3288_CLK_SDMMC_SAMPLE: 828 case RK3288_CLK_MAC: 829 case RK3288_ACLK_GMAC: 830 case RK3288_PCLK_GMAC: 831 case RK3288_PCLK_I2C0: 832 case RK3288_PCLK_I2C1: 833 case RK3288_PCLK_I2C2: 834 case RK3288_PCLK_I2C3: 835 case RK3288_PCLK_I2C4: 836 case RK3288_PCLK_I2C5: 837 case RK3288_PCLK_TSADC: 838 case RK3288_HCLK_HOST0: 839 case RK3288_HCLK_SDMMC: 840 /* Enabled by default. */ 841 break; 842 default: 843 printf("%s: 0x%08x\n", __func__, idx); 844 break; 845 } 846 } 847 848 void 849 rk3288_reset(void *cookie, uint32_t *cells, int on) 850 { 851 struct rkclock_softc *sc = cookie; 852 uint32_t idx = cells[0]; 853 uint32_t mask = (1 << (idx % 16)); 854 855 HWRITE4(sc, RK3288_CRU_SOFTRST_CON(idx / 16), 856 mask << 16 | (on ? mask : 0)); 857 } 858 859 /* 860 * Rockchip RK3308 861 */ 862 863 struct rkclock rk3308_clocks[] = { 864 { 865 RK3308_CLK_RTC32K, RK3308_CRU_CLKSEL_CON(2), 866 SEL(10, 9), 0, 867 { RK3308_PLL_VPLL0, RK3308_PLL_VPLL1 } 868 }, 869 { 870 RK3308_CLK_UART0, RK3308_CRU_CLKSEL_CON(10), 871 SEL(15, 13), DIV(4, 0), 872 { RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1, 873 RK3308_USB480M, RK3308_XIN24M } 874 }, 875 { 876 RK3308_CLK_UART1, RK3308_CRU_CLKSEL_CON(13), 877 SEL(15, 13), DIV(4, 0), 878 { RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1, 879 RK3308_USB480M, RK3308_XIN24M } 880 }, 881 { 882 RK3308_CLK_UART2, RK3308_CRU_CLKSEL_CON(16), 883 SEL(15, 13), DIV(4, 0), 884 { RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1, 885 RK3308_USB480M, RK3308_XIN24M } 886 }, 887 { 888 RK3308_CLK_UART3, RK3308_CRU_CLKSEL_CON(19), 889 SEL(15, 13), DIV(4, 0), 890 { RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1, 891 RK3308_USB480M, RK3308_XIN24M } 892 }, 893 { 894 RK3308_CLK_UART4, RK3308_CRU_CLKSEL_CON(22), 895 SEL(15, 13), DIV(4, 0), 896 { RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1, 897 RK3308_USB480M, RK3308_XIN24M } 898 }, 899 { 900 RK3308_CLK_PWM0, RK3308_CRU_CLKSEL_CON(29), 901 SEL(15, 14), DIV(6, 0), 902 { RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_XIN24M } 903 }, 904 { 905 RK3308_CLK_TSADC, RK3308_CRU_CLKSEL_CON(33), 906 0, DIV(10, 0), 907 { RK3308_XIN24M } 908 }, 909 { 910 RK3308_CLK_SARADC, RK3308_CRU_CLKSEL_CON(34), 911 0, DIV(10, 0), 912 { RK3308_XIN24M } 913 }, 914 { 915 RK3308_CLK_CRYPTO, RK3308_CRU_CLKSEL_CON(7), 916 SEL(7, 6), DIV(4, 0), 917 { RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1, 0 } 918 }, 919 { 920 RK3308_CLK_CRYPTO_APK, RK3308_CRU_CLKSEL_CON(7), 921 SEL(15, 14), DIV(12, 8), 922 { RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1, 0 } 923 }, 924 { 925 RK3308_CLK_SDMMC, RK3308_CRU_CLKSEL_CON(39), 926 SEL(9, 8), DIV(7, 0), 927 { RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1, 928 RK3308_XIN24M } 929 }, 930 { 931 RK3308_CLK_SDIO, RK3308_CRU_CLKSEL_CON(40), 932 SEL(9, 8), DIV(7, 0), 933 { RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1, 934 RK3308_XIN24M } 935 }, 936 { 937 RK3308_CLK_EMMC, RK3308_CRU_CLKSEL_CON(41), 938 SEL(9, 8), DIV(7, 0), 939 { RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1, 940 RK3308_XIN24M } 941 }, 942 { 943 RK3308_CLK_MAC_SRC, RK3308_CRU_CLKSEL_CON(43), 944 SEL(7, 6), DIV(4, 0), 945 { RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1, 0 } 946 }, 947 { 948 RK3308_CLK_MAC, RK3308_CRU_CLKSEL_CON(43), 949 SEL(14, 13), 0, 950 { RK3308_CLK_MAC_SRC, 0 }, 951 SET_PARENT 952 }, 953 { 954 RK3308_ACLK_PERI_SRC, RK3308_CRU_CLKSEL_CON(36), 955 SEL(7, 6), 0, 956 { RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1, 0 } 957 }, 958 { 959 RK3308_PCLK_PERI, RK3308_CRU_CLKSEL_CON(37), 960 0, DIV(12, 8), 961 { RK3308_ACLK_PERI_SRC } 962 }, 963 { 964 RK3308_PCLK_MAC, 0, 0, 0, 965 { RK3308_PCLK_PERI } 966 }, 967 968 { 969 /* Sentinel */ 970 } 971 }; 972 973 void 974 rk3308_init(struct rkclock_softc *sc) 975 { 976 int i; 977 978 /* The code below assumes all clocks are enabled. Check this!. */ 979 for (i = 0; i <= 14; i++) { 980 if (HREAD4(sc, RK3308_CRU_CLKGATE_CON(i)) != 0x00000000) { 981 printf("CRU_CLKGATE_CON%d: 0x%08x\n", i, 982 HREAD4(sc, RK3308_CRU_CLKGATE_CON(i))); 983 } 984 } 985 sc->sc_clocks = rk3308_clocks; 986 } 987 988 uint32_t 989 rk3308_armclk_parent(uint32_t mux) 990 { 991 switch (mux) { 992 case 0: 993 return RK3308_PLL_APLL; 994 case 1: 995 return RK3308_PLL_VPLL0; 996 case 2: 997 return RK3308_PLL_VPLL1; 998 } 999 1000 return 0; 1001 } 1002 1003 uint32_t 1004 rk3308_get_armclk(struct rkclock_softc *sc) 1005 { 1006 uint32_t reg, mux, div_con; 1007 uint32_t idx; 1008 1009 reg = HREAD4(sc, RK3308_CRU_CLKSEL_CON(0)); 1010 mux = (reg & RK3308_CRU_CORE_CLK_PLL_SEL_MASK) >> 1011 RK3308_CRU_CORE_CLK_PLL_SEL_SHIFT; 1012 div_con = (reg & RK3308_CRU_CLK_CORE_DIV_CON_MASK) >> 1013 RK3308_CRU_CLK_CORE_DIV_CON_SHIFT; 1014 idx = rk3308_armclk_parent(mux); 1015 1016 return rk3308_get_frequency(sc, &idx) / (div_con + 1); 1017 } 1018 1019 int 1020 rk3308_set_armclk(struct rkclock_softc *sc, uint32_t freq) 1021 { 1022 uint32_t reg, mux; 1023 uint32_t old_freq, div; 1024 uint32_t idx; 1025 1026 old_freq = rk3308_get_armclk(sc); 1027 if (freq == old_freq) 1028 return 0; 1029 1030 reg = HREAD4(sc, RK3308_CRU_CLKSEL_CON(0)); 1031 mux = (reg & RK3308_CRU_CORE_CLK_PLL_SEL_MASK) >> 1032 RK3308_CRU_CORE_CLK_PLL_SEL_SHIFT; 1033 1034 /* Keep the pclk_dbg clock at or below 300 MHz. */ 1035 div = 1; 1036 while (freq / (div + 1) > 300000000) 1037 div++; 1038 /* and make sure we use an odd divider. */ 1039 if ((div % 2) == 0) 1040 div++; 1041 1042 /* When ramping up, set clock dividers first. */ 1043 if (freq > old_freq) { 1044 HWRITE4(sc, RK3308_CRU_CLKSEL_CON(0), 1045 RK3308_CRU_CLK_CORE_DIV_CON_MASK << 16 | 1046 0 << RK3308_CRU_CLK_CORE_DIV_CON_SHIFT | 1047 RK3308_CRU_ACLK_CORE_DIV_CON_MASK << 16 | 1048 1 << RK3308_CRU_ACLK_CORE_DIV_CON_SHIFT | 1049 RK3308_CRU_CLK_CORE_DBG_DIV_CON_MASK << 16 | 1050 div << RK3308_CRU_CLK_CORE_DBG_DIV_CON_SHIFT); 1051 } 1052 1053 /* We always use VPLL1 and force the switch below if needed. */ 1054 idx = RK3308_PLL_VPLL1; 1055 rk3308_set_frequency(sc, &idx, freq); 1056 1057 /* When ramping down, set clock dividers last. */ 1058 if (freq < old_freq || mux != 2) { 1059 HWRITE4(sc, RK3308_CRU_CLKSEL_CON(0), 1060 RK3308_CRU_CORE_CLK_PLL_SEL_MASK << 16 | 1061 2 << RK3308_CRU_CORE_CLK_PLL_SEL_SHIFT | 1062 RK3308_CRU_CLK_CORE_DIV_CON_MASK << 16 | 1063 0 << RK3308_CRU_CLK_CORE_DIV_CON_SHIFT | 1064 RK3308_CRU_ACLK_CORE_DIV_CON_MASK << 16 | 1065 1 << RK3308_CRU_ACLK_CORE_DIV_CON_SHIFT | 1066 RK3308_CRU_CLK_CORE_DBG_DIV_CON_MASK << 16 | 1067 div << RK3308_CRU_CLK_CORE_DBG_DIV_CON_SHIFT); 1068 } 1069 1070 return 0; 1071 } 1072 1073 uint32_t 1074 rk3308_get_pll(struct rkclock_softc *sc, bus_size_t base) 1075 { 1076 uint32_t fbdiv, postdiv1, postdiv2, refdiv; 1077 uint32_t dsmpd, fracdiv; 1078 uint64_t frac = 0; 1079 uint32_t reg; 1080 1081 reg = HREAD4(sc, base + 0x0000); 1082 postdiv1 = (reg & RK3308_CRU_PLL_POSTDIV1_MASK) >> 1083 RK3308_CRU_PLL_POSTDIV1_SHIFT; 1084 fbdiv = (reg & RK3308_CRU_PLL_FBDIV_MASK) >> 1085 RK3308_CRU_PLL_FBDIV_SHIFT; 1086 reg = HREAD4(sc, base + 0x0004); 1087 dsmpd = (reg & RK3308_CRU_PLL_DSMPD); 1088 postdiv2 = (reg & RK3308_CRU_PLL_POSTDIV2_MASK) >> 1089 RK3308_CRU_PLL_POSTDIV2_SHIFT; 1090 refdiv = (reg & RK3308_CRU_PLL_REFDIV_MASK) >> 1091 RK3308_CRU_PLL_REFDIV_SHIFT; 1092 reg = HREAD4(sc, base + 0x0008); 1093 fracdiv = (reg & RK3308_CRU_PLL_FRACDIV_MASK) >> 1094 RK3308_CRU_PLL_FRACDIV_SHIFT; 1095 1096 if (dsmpd == 0) 1097 frac = (24000000ULL * fracdiv / refdiv) >> 24; 1098 return ((24000000ULL * fbdiv / refdiv) + frac) / postdiv1 / postdiv2; 1099 } 1100 1101 int 1102 rk3308_set_pll(struct rkclock_softc *sc, bus_size_t base, uint32_t freq) 1103 { 1104 uint32_t fbdiv, postdiv1, postdiv2, refdiv; 1105 int mode_shift = -1; 1106 1107 switch (base) { 1108 case RK3308_CRU_APLL_CON(0): 1109 mode_shift = 0; 1110 break; 1111 case RK3308_CRU_DPLL_CON(0): 1112 mode_shift = 2; 1113 break; 1114 case RK3308_CRU_VPLL0_CON(0): 1115 mode_shift = 4; 1116 break; 1117 case RK3308_CRU_VPLL1_CON(0): 1118 mode_shift = 6; 1119 break; 1120 } 1121 KASSERT(mode_shift != -1); 1122 1123 /* 1124 * It is not clear whether all combinations of the clock 1125 * dividers result in a stable clock. Therefore this function 1126 * only supports a limited set of PLL clock rates. For now 1127 * this set covers all the CPU frequencies supported by the 1128 * Linux kernel. 1129 */ 1130 switch (freq) { 1131 case 1608000000U: 1132 case 1584000000U: 1133 case 1560000000U: 1134 case 1536000000U: 1135 case 1512000000U: 1136 case 1488000000U: 1137 case 1464000000U: 1138 case 1440000000U: 1139 case 1416000000U: 1140 case 1392000000U: 1141 case 1368000000U: 1142 case 1344000000U: 1143 case 1320000000U: 1144 case 1296000000U: 1145 case 1272000000U: 1146 case 1248000000U: 1147 case 1200000000U: 1148 case 1104000000U: 1149 postdiv1 = postdiv2 = refdiv = 1; 1150 break; 1151 case 1188000000U: 1152 refdiv = 2; postdiv1 = postdiv2 = 1; 1153 break; 1154 case 1100000000U: 1155 refdiv = 12; postdiv1 = postdiv2 = 1; 1156 break; 1157 case 1000000000U: 1158 refdiv = 6; postdiv1 = postdiv2 = 1; 1159 break; 1160 case 1008000000U: 1161 case 984000000U: 1162 case 960000000U: 1163 case 936000000U: 1164 case 912000000U: 1165 case 888000000U: 1166 case 864000000U: 1167 case 840000000U: 1168 case 816000000U: 1169 case 696000000U: 1170 case 624000000U: 1171 postdiv1 = 2; postdiv2 = refdiv = 1; 1172 break; 1173 case 900000000U: 1174 refdiv = 4; postdiv1 = 2; postdiv2 = 1; 1175 break; 1176 case 800000000U: 1177 case 700000000U: 1178 case 500000000U: 1179 refdiv = 6; postdiv1 = 2; postdiv2 = 1; 1180 break; 1181 case 600000000U: 1182 case 504000000U: 1183 postdiv1 = 3; postdiv2 = refdiv = 1; 1184 break; 1185 case 594000000U: 1186 refdiv = 2; postdiv1 = 2; postdiv2 = 1; 1187 break; 1188 case 408000000U: 1189 case 312000000U: 1190 postdiv1 = postdiv2 = 2; refdiv = 1; 1191 break; 1192 case 216000000U: 1193 postdiv1 = 4; postdiv2 = 2; refdiv = 1; 1194 break; 1195 case 96000000U: 1196 postdiv1 = postdiv2 = 4; refdiv = 1; 1197 break; 1198 default: 1199 printf("%s: %u Hz\n", __func__, freq); 1200 return -1; 1201 } 1202 1203 /* Calculate feedback divider. */ 1204 fbdiv = freq * postdiv1 * postdiv2 * refdiv / 24000000; 1205 1206 /* 1207 * Select slow mode to guarantee a stable clock while we're 1208 * adjusting the PLL. 1209 */ 1210 HWRITE4(sc, RK3308_CRU_CRU_MODE, 1211 (RK3308_CRU_CRU_MODE_MASK << 16 | 1212 RK3308_CRU_CRU_MODE_SLOW) << mode_shift); 1213 1214 /* Set PLL rate. */ 1215 HWRITE4(sc, base + 0x0000, 1216 RK3308_CRU_PLL_POSTDIV1_MASK << 16 | 1217 postdiv1 << RK3308_CRU_PLL_POSTDIV1_SHIFT | 1218 RK3308_CRU_PLL_FBDIV_MASK << 16 | 1219 fbdiv << RK3308_CRU_PLL_FBDIV_SHIFT); 1220 HWRITE4(sc, base + 0x0004, 1221 RK3308_CRU_PLL_DSMPD << 16 | RK3308_CRU_PLL_DSMPD | 1222 RK3308_CRU_PLL_POSTDIV2_MASK << 16 | 1223 postdiv2 << RK3308_CRU_PLL_POSTDIV2_SHIFT | 1224 RK3308_CRU_PLL_REFDIV_MASK << 16 | 1225 refdiv << RK3308_CRU_PLL_REFDIV_SHIFT); 1226 1227 /* Wait for PLL to stabilize. */ 1228 while ((HREAD4(sc, base + 0x0004) & RK3308_CRU_PLL_PLL_LOCK) == 0) 1229 delay(10); 1230 1231 /* Switch back to normal mode. */ 1232 HWRITE4(sc, RK3308_CRU_CRU_MODE, 1233 (RK3308_CRU_CRU_MODE_MASK << 16 | 1234 RK3308_CRU_CRU_MODE_NORMAL) << mode_shift); 1235 1236 return 0; 1237 } 1238 1239 uint32_t 1240 rk3308_get_rtc32k(struct rkclock_softc *sc) 1241 { 1242 uint32_t reg, mux, pll, div_con; 1243 1244 reg = HREAD4(sc, RK3308_CRU_CLKSEL_CON(2)); 1245 mux = (reg & 0x30) >> 8; 1246 if (mux != 3) { 1247 printf("%s: RTC32K not using clk_32k_div\n", __func__); 1248 return 0; 1249 } 1250 1251 if ((reg >> 10) & 1) 1252 pll = RK3308_PLL_VPLL1; 1253 else 1254 pll = RK3308_PLL_VPLL0; 1255 1256 div_con = HREAD4(sc, RK3308_CRU_CLKSEL_CON(4)) & 0xffff; 1257 return rk3308_get_frequency(sc, &pll) / (div_con + 1); 1258 } 1259 1260 int 1261 rk3308_set_rtc32k(struct rkclock_softc *sc, uint32_t freq) 1262 { 1263 struct rkclock *clk; 1264 uint32_t vpll0_freq, vpll1_freq, mux, div_con; 1265 1266 clk = rkclock_lookup(sc, RK3308_CLK_RTC32K); 1267 vpll0_freq = rkclock_freq(sc, clk, 0, freq); 1268 vpll1_freq = rkclock_freq(sc, clk, 1, freq); 1269 mux = 0; 1270 freq = vpll0_freq; 1271 1272 if ((vpll1_freq > vpll0_freq && vpll1_freq <= freq) || 1273 (vpll1_freq < vpll0_freq && vpll1_freq >= freq)) { 1274 mux = 1; 1275 freq = vpll1_freq; 1276 } 1277 1278 div_con = rkclock_div_con(sc, clk, mux, freq); 1279 HWRITE4(sc, RK3308_CRU_CLKSEL_CON(2), 1 << 26 | (mux << 10)); 1280 HWRITE4(sc, RK3308_CRU_CLKSEL_CON(4), 0xffff0000 | div_con); 1281 return 0; 1282 } 1283 1284 uint32_t 1285 rk3308_get_frequency(void *cookie, uint32_t *cells) 1286 { 1287 struct rkclock_softc *sc = cookie; 1288 uint32_t idx = cells[0]; 1289 1290 switch (idx) { 1291 case RK3308_PLL_APLL: 1292 return rk3308_get_pll(sc, RK3308_CRU_APLL_CON(0)); 1293 case RK3308_PLL_DPLL: 1294 return rk3308_get_pll(sc, RK3308_CRU_DPLL_CON(0)); 1295 case RK3308_PLL_VPLL0: 1296 return rk3308_get_pll(sc, RK3308_CRU_VPLL0_CON(0)); 1297 case RK3308_PLL_VPLL1: 1298 return rk3308_get_pll(sc, RK3308_CRU_VPLL1_CON(0)); 1299 case RK3308_ARMCLK: 1300 return rk3308_get_armclk(sc); 1301 case RK3308_XIN24M: 1302 return 24000000; 1303 case RK3308_CLK_RTC32K: 1304 return rk3308_get_rtc32k(sc); 1305 1306 /* 1307 * XXX The USB480M clock is external. Returning zero here will cause 1308 * it to be ignored for reparenting purposes. 1309 */ 1310 case RK3308_USB480M: 1311 return 0; 1312 default: 1313 break; 1314 } 1315 1316 return rkclock_get_frequency(sc, idx); 1317 } 1318 1319 int 1320 rk3308_set_frequency(void *cookie, uint32_t *cells, uint32_t freq) 1321 { 1322 struct rkclock_softc *sc = cookie; 1323 uint32_t idx = cells[0]; 1324 1325 switch (idx) { 1326 case RK3308_PLL_APLL: 1327 return rk3308_set_pll(sc, RK3308_CRU_APLL_CON(0), freq); 1328 case RK3308_PLL_DPLL: 1329 return rk3308_set_pll(sc, RK3308_CRU_DPLL_CON(0), freq); 1330 case RK3308_PLL_VPLL0: 1331 return rk3308_set_pll(sc, RK3308_CRU_VPLL0_CON(0), freq); 1332 case RK3308_PLL_VPLL1: 1333 return rk3308_set_pll(sc, RK3308_CRU_VPLL1_CON(0), freq); 1334 case RK3308_ARMCLK: 1335 return rk3308_set_armclk(sc, freq); 1336 case RK3308_CLK_RTC32K: 1337 return rk3308_set_rtc32k(sc, freq); 1338 default: 1339 break; 1340 } 1341 1342 return rkclock_set_frequency(sc, idx, freq); 1343 } 1344 1345 1346 int 1347 rk3308_set_parent(void *cookie, uint32_t *cells, uint32_t *pcells) 1348 { 1349 struct rkclock_softc *sc = cookie; 1350 1351 if (pcells[0] != sc->sc_phandle) 1352 return -1; 1353 1354 return rkclock_set_parent(sc, cells[0], pcells[1]); 1355 } 1356 1357 void 1358 rk3308_enable(void *cookie, uint32_t *cells, int on) 1359 { 1360 uint32_t idx = cells[0]; 1361 1362 /* 1363 * All clocks are enabled by default, so there is nothing for 1364 * us to do until we start disabling clocks. 1365 */ 1366 if (!on) 1367 printf("%s: 0x%08x\n", __func__, idx); 1368 } 1369 1370 void 1371 rk3308_reset(void *cookie, uint32_t *cells, int on) 1372 { 1373 struct rkclock_softc *sc = cookie; 1374 uint32_t idx = cells[0]; 1375 uint32_t mask = (1 << (idx % 16)); 1376 1377 HWRITE4(sc, RK3308_CRU_SOFTRST_CON(idx / 16), 1378 mask << 16 | (on ? mask : 0)); 1379 } 1380 1381 1382 /* 1383 * Rockchip RK3328 1384 */ 1385 1386 struct rkclock rk3328_clocks[] = { 1387 { 1388 RK3328_CLK_RTC32K, RK3328_CRU_CLKSEL_CON(38), 1389 SEL(15, 14), DIV(13, 0), 1390 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_XIN24M } 1391 }, 1392 { 1393 RK3328_CLK_SDMMC, RK3328_CRU_CLKSEL_CON(30), 1394 SEL(9, 8), DIV(7, 0), 1395 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_XIN24M, 1396 RK3328_USB480M } 1397 }, 1398 { 1399 RK3328_CLK_SDIO, RK3328_CRU_CLKSEL_CON(31), 1400 SEL(9, 8), DIV(7, 0), 1401 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_XIN24M, 1402 RK3328_USB480M } 1403 }, 1404 { 1405 RK3328_CLK_EMMC, RK3328_CRU_CLKSEL_CON(32), 1406 SEL(9, 8), DIV(7, 0), 1407 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_XIN24M, 1408 RK3328_USB480M } 1409 }, 1410 { 1411 RK3328_CLK_TSADC, RK3328_CRU_CLKSEL_CON(22), 1412 0, DIV(9, 0), 1413 { RK3328_CLK_24M } 1414 }, 1415 { 1416 RK3328_CLK_UART0, RK3328_CRU_CLKSEL_CON(14), 1417 SEL(9, 8), 0, 1418 { 0, 0, RK3328_XIN24M, RK3328_XIN24M } 1419 }, 1420 { 1421 RK3328_CLK_UART1, RK3328_CRU_CLKSEL_CON(16), 1422 SEL(9, 8), 0, 1423 { 0, 0, RK3328_XIN24M, RK3328_XIN24M } 1424 }, 1425 { 1426 RK3328_CLK_UART2, RK3328_CRU_CLKSEL_CON(18), 1427 SEL(9, 8), 0, 1428 { 0, 0, RK3328_XIN24M, RK3328_XIN24M } 1429 }, 1430 { 1431 RK3328_CLK_WIFI, RK3328_CRU_CLKSEL_CON(52), 1432 SEL(7, 6), DIV(5, 0), 1433 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_USB480M } 1434 }, 1435 { 1436 RK3328_CLK_I2C0, RK3328_CRU_CLKSEL_CON(34), 1437 SEL(7, 7), DIV(6, 0), 1438 { RK3328_PLL_CPLL, RK3328_PLL_GPLL } 1439 }, 1440 { 1441 RK3328_CLK_I2C1, RK3328_CRU_CLKSEL_CON(34), 1442 SEL(15, 15), DIV(14, 8), 1443 { RK3328_PLL_CPLL, RK3328_PLL_GPLL } 1444 }, 1445 { 1446 RK3328_CLK_I2C2, RK3328_CRU_CLKSEL_CON(35), 1447 SEL(7, 7), DIV(6, 0), 1448 { RK3328_PLL_CPLL, RK3328_PLL_GPLL } 1449 }, 1450 { 1451 RK3328_CLK_I2C3, RK3328_CRU_CLKSEL_CON(35), 1452 SEL(15, 15), DIV(14, 8), 1453 { RK3328_PLL_CPLL, RK3328_PLL_GPLL } 1454 }, 1455 { 1456 RK3328_CLK_CRYPTO, RK3328_CRU_CLKSEL_CON(20), 1457 SEL(7, 7), DIV(4, 0), 1458 { RK3328_PLL_CPLL, RK3328_PLL_GPLL } 1459 }, 1460 { 1461 RK3328_CLK_PDM, RK3328_CRU_CLKSEL_CON(20), 1462 SEL(15, 14), DIV(12, 8), 1463 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_PLL_APLL }, 1464 FIXED_PARENT | SET_PARENT 1465 }, 1466 { 1467 RK3328_CLK_VDEC_CABAC, RK3328_CRU_CLKSEL_CON(48), 1468 SEL(15, 14), DIV(12, 8), 1469 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY, 1470 RK3328_USB480M } 1471 }, 1472 { 1473 RK3328_CLK_VDEC_CORE, RK3328_CRU_CLKSEL_CON(49), 1474 SEL(7, 6), DIV(4, 0), 1475 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY, 1476 RK3328_USB480M } 1477 }, 1478 { 1479 RK3328_CLK_VENC_DSP, RK3328_CRU_CLKSEL_CON(52), 1480 SEL(15, 14), DIV(12, 8), 1481 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY, 1482 RK3328_USB480M } 1483 }, 1484 { 1485 RK3328_CLK_VENC_CORE, RK3328_CRU_CLKSEL_CON(51), 1486 SEL(15, 14), DIV(12, 8), 1487 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY, 1488 RK3328_USB480M } 1489 }, 1490 { 1491 RK3328_CLK_TSP, RK3328_CRU_CLKSEL_CON(21), 1492 SEL(15, 15), DIV(12, 8), 1493 { RK3328_PLL_CPLL, RK3328_PLL_GPLL } 1494 }, 1495 { 1496 RK3328_CLK_MAC2IO_SRC, RK3328_CRU_CLKSEL_CON(27), 1497 SEL(7, 7), DIV(4, 0), 1498 { RK3328_PLL_CPLL, RK3328_PLL_GPLL } 1499 }, 1500 { 1501 RK3328_DCLK_LCDC, RK3328_CRU_CLKSEL_CON(40), 1502 SEL(1, 1), 0, 1503 { RK3328_HDMIPHY, RK3328_DCLK_LCDC_SRC } 1504 }, 1505 { 1506 RK3328_ACLK_VOP_PRE, RK3328_CRU_CLKSEL_CON(39), 1507 SEL(7, 6), DIV(4, 0), 1508 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY, 1509 RK3328_USB480M } 1510 }, 1511 { 1512 RK3328_ACLK_RGA_PRE, RK3328_CRU_CLKSEL_CON(36), 1513 SEL(15, 14), DIV(12, 8), 1514 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY, 1515 RK3328_USB480M } 1516 }, 1517 { 1518 RK3328_ACLK_BUS_PRE, RK3328_CRU_CLKSEL_CON(0), 1519 SEL(14, 13), DIV(12, 8), 1520 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY } 1521 }, 1522 { 1523 RK3328_ACLK_PERI_PRE, RK3328_CRU_CLKSEL_CON(28), 1524 SEL(7, 6), DIV(4, 0), 1525 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY } 1526 }, 1527 { 1528 RK3328_ACLK_RKVDEC_PRE, RK3328_CRU_CLKSEL_CON(48), 1529 SEL(7, 6), DIV(4, 0), 1530 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY, 1531 RK3328_USB480M } 1532 }, 1533 { 1534 RK3328_ACLK_RKVENC, RK3328_CRU_CLKSEL_CON(51), 1535 SEL(7, 6), DIV(4, 0), 1536 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY, 1537 RK3328_USB480M } 1538 }, 1539 { 1540 RK3328_ACLK_VPU_PRE, RK3328_CRU_CLKSEL_CON(50), 1541 SEL(7, 6), DIV(4, 0), 1542 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY, 1543 RK3328_USB480M } 1544 }, 1545 { 1546 RK3328_ACLK_VIO_PRE, RK3328_CRU_CLKSEL_CON(37), 1547 SEL(7, 6), DIV(4, 0), 1548 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY, 1549 RK3328_USB480M } 1550 }, 1551 { 1552 RK3328_PCLK_BUS_PRE, RK3328_CRU_CLKSEL_CON(1), 1553 0, DIV(14, 12), 1554 { RK3328_ACLK_BUS_PRE } 1555 }, 1556 { 1557 RK3328_HCLK_BUS_PRE, RK3328_CRU_CLKSEL_CON(1), 1558 0, DIV(9, 8), 1559 { RK3328_ACLK_BUS_PRE } 1560 }, 1561 { 1562 RK3328_PCLK_PERI, RK3328_CRU_CLKSEL_CON(29), 1563 0, DIV(6, 4), 1564 { RK3328_ACLK_PERI_PRE } 1565 }, 1566 { 1567 RK3328_HCLK_PERI, RK3328_CRU_CLKSEL_CON(29), 1568 0, DIV(1, 0), 1569 { RK3328_ACLK_PERI_PRE } 1570 }, 1571 { 1572 RK3328_CLK_24M, RK3328_CRU_CLKSEL_CON(2), 1573 0, DIV(12, 8), 1574 { RK3328_XIN24M } 1575 }, 1576 { 1577 /* Sentinel */ 1578 } 1579 }; 1580 1581 void 1582 rk3328_init(struct rkclock_softc *sc) 1583 { 1584 int i; 1585 1586 /* The code below assumes all clocks are enabled. Check this!. */ 1587 for (i = 0; i <= 28; i++) { 1588 if (HREAD4(sc, RK3328_CRU_CLKGATE_CON(i)) != 0x00000000) { 1589 printf("CRU_CLKGATE_CON%d: 0x%08x\n", i, 1590 HREAD4(sc, RK3328_CRU_CLKGATE_CON(i))); 1591 } 1592 } 1593 1594 sc->sc_clocks = rk3328_clocks; 1595 } 1596 1597 uint32_t 1598 rk3328_armclk_parent(uint32_t mux) 1599 { 1600 switch (mux) { 1601 case 0: 1602 return RK3328_PLL_APLL; 1603 case 1: 1604 return RK3328_PLL_GPLL; 1605 case 2: 1606 return RK3328_PLL_DPLL; 1607 case 3: 1608 return RK3328_PLL_NPLL; 1609 } 1610 1611 return 0; 1612 } 1613 1614 uint32_t 1615 rk3328_get_armclk(struct rkclock_softc *sc) 1616 { 1617 uint32_t reg, mux, div_con; 1618 uint32_t idx; 1619 1620 reg = HREAD4(sc, RK3328_CRU_CLKSEL_CON(0)); 1621 mux = (reg & RK3328_CRU_CORE_CLK_PLL_SEL_MASK) >> 1622 RK3328_CRU_CORE_CLK_PLL_SEL_SHIFT; 1623 div_con = (reg & RK3328_CRU_CLK_CORE_DIV_CON_MASK) >> 1624 RK3328_CRU_CLK_CORE_DIV_CON_SHIFT; 1625 idx = rk3328_armclk_parent(mux); 1626 1627 return rk3328_get_frequency(sc, &idx) / (div_con + 1); 1628 } 1629 1630 int 1631 rk3328_set_armclk(struct rkclock_softc *sc, uint32_t freq) 1632 { 1633 uint32_t reg, mux; 1634 uint32_t old_freq, div; 1635 uint32_t idx; 1636 1637 old_freq = rk3328_get_armclk(sc); 1638 if (freq == old_freq) 1639 return 0; 1640 1641 reg = HREAD4(sc, RK3328_CRU_CLKSEL_CON(0)); 1642 mux = (reg & RK3328_CRU_CORE_CLK_PLL_SEL_MASK) >> 1643 RK3328_CRU_CORE_CLK_PLL_SEL_SHIFT; 1644 1645 /* Keep the pclk_dbg clock at or below 300 MHz. */ 1646 div = 1; 1647 while (freq / (div + 1) > 300000000) 1648 div++; 1649 /* and make sure we use an odd divider. */ 1650 if ((div % 2) == 0) 1651 div++; 1652 1653 /* When ramping up, set clock dividers first. */ 1654 if (freq > old_freq) { 1655 HWRITE4(sc, RK3328_CRU_CLKSEL_CON(0), 1656 RK3328_CRU_CLK_CORE_DIV_CON_MASK << 16 | 1657 0 << RK3328_CRU_CLK_CORE_DIV_CON_SHIFT); 1658 HWRITE4(sc, RK3328_CRU_CLKSEL_CON(1), 1659 RK3328_CRU_ACLK_CORE_DIV_CON_MASK << 16 | 1660 1 << RK3328_CRU_ACLK_CORE_DIV_CON_SHIFT | 1661 RK3328_CRU_CLK_CORE_DBG_DIV_CON_MASK << 16 | 1662 div << RK3328_CRU_CLK_CORE_DBG_DIV_CON_SHIFT); 1663 } 1664 1665 /* We always use NPLL and force the switch below if needed. */ 1666 idx = RK3328_PLL_NPLL; 1667 rk3328_set_frequency(sc, &idx, freq); 1668 1669 /* When ramping down, set clock dividers last. */ 1670 if (freq < old_freq || mux != 3) { 1671 HWRITE4(sc, RK3328_CRU_CLKSEL_CON(0), 1672 RK3328_CRU_CORE_CLK_PLL_SEL_MASK << 16 | 1673 3 << RK3328_CRU_CORE_CLK_PLL_SEL_SHIFT | 1674 RK3328_CRU_CLK_CORE_DIV_CON_MASK << 16 | 1675 0 << RK3328_CRU_CLK_CORE_DIV_CON_SHIFT); 1676 HWRITE4(sc, RK3328_CRU_CLKSEL_CON(1), 1677 RK3328_CRU_ACLK_CORE_DIV_CON_MASK << 16 | 1678 1 << RK3328_CRU_ACLK_CORE_DIV_CON_SHIFT | 1679 RK3328_CRU_CLK_CORE_DBG_DIV_CON_MASK << 16 | 1680 div << RK3328_CRU_CLK_CORE_DBG_DIV_CON_SHIFT); 1681 } 1682 1683 return 0; 1684 } 1685 1686 uint32_t 1687 rk3328_get_pll(struct rkclock_softc *sc, bus_size_t base) 1688 { 1689 uint32_t fbdiv, postdiv1, postdiv2, refdiv; 1690 uint32_t dsmpd, fracdiv; 1691 uint64_t frac = 0; 1692 uint32_t reg; 1693 1694 reg = HREAD4(sc, base + 0x0000); 1695 postdiv1 = (reg & RK3328_CRU_PLL_POSTDIV1_MASK) >> 1696 RK3328_CRU_PLL_POSTDIV1_SHIFT; 1697 fbdiv = (reg & RK3328_CRU_PLL_FBDIV_MASK) >> 1698 RK3328_CRU_PLL_FBDIV_SHIFT; 1699 reg = HREAD4(sc, base + 0x0004); 1700 dsmpd = (reg & RK3328_CRU_PLL_DSMPD); 1701 postdiv2 = (reg & RK3328_CRU_PLL_POSTDIV2_MASK) >> 1702 RK3328_CRU_PLL_POSTDIV2_SHIFT; 1703 refdiv = (reg & RK3328_CRU_PLL_REFDIV_MASK) >> 1704 RK3328_CRU_PLL_REFDIV_SHIFT; 1705 reg = HREAD4(sc, base + 0x0008); 1706 fracdiv = (reg & RK3328_CRU_PLL_FRACDIV_MASK) >> 1707 RK3328_CRU_PLL_FRACDIV_SHIFT; 1708 1709 if (dsmpd == 0) 1710 frac = (24000000ULL * fracdiv / refdiv) >> 24; 1711 return ((24000000ULL * fbdiv / refdiv) + frac) / postdiv1 / postdiv2; 1712 } 1713 1714 int 1715 rk3328_set_pll(struct rkclock_softc *sc, bus_size_t base, uint32_t freq) 1716 { 1717 uint32_t fbdiv, postdiv1, postdiv2, refdiv; 1718 int mode_shift = -1; 1719 1720 switch (base) { 1721 case RK3328_CRU_APLL_CON(0): 1722 mode_shift = 0; 1723 break; 1724 case RK3328_CRU_DPLL_CON(0): 1725 mode_shift = 4; 1726 break; 1727 case RK3328_CRU_CPLL_CON(0): 1728 mode_shift = 8; 1729 break; 1730 case RK3328_CRU_GPLL_CON(0): 1731 mode_shift = 12; 1732 break; 1733 case RK3328_CRU_NPLL_CON(0): 1734 mode_shift = 1; 1735 break; 1736 } 1737 KASSERT(mode_shift != -1); 1738 1739 /* 1740 * It is not clear whether all combinations of the clock 1741 * dividers result in a stable clock. Therefore this function 1742 * only supports a limited set of PLL clock rates. For now 1743 * this set covers all the CPU frequencies supported by the 1744 * Linux kernel. 1745 */ 1746 switch (freq) { 1747 case 1800000000U: 1748 case 1704000000U: 1749 case 1608000000U: 1750 case 1512000000U: 1751 case 1488000000U: 1752 case 1416000000U: 1753 case 1392000000U: 1754 case 1296000000U: 1755 case 1200000000U: 1756 case 1104000000U: 1757 postdiv1 = postdiv2 = refdiv = 1; 1758 break; 1759 case 1008000000U: 1760 case 912000000U: 1761 case 816000000U: 1762 case 696000000U: 1763 postdiv1 = 2; postdiv2 = refdiv = 1; 1764 break; 1765 case 600000000U: 1766 postdiv1 = 3; postdiv2 = refdiv = 1; 1767 break; 1768 case 408000000U: 1769 case 312000000U: 1770 postdiv1 = postdiv2 = 2; refdiv = 1; 1771 break; 1772 case 216000000U: 1773 postdiv1 = 4; postdiv2 = 2; refdiv = 1; 1774 break; 1775 case 96000000U: 1776 postdiv1 = postdiv2 = 4; refdiv = 1; 1777 break; 1778 default: 1779 printf("%s: %u Hz\n", __func__, freq); 1780 return -1; 1781 } 1782 1783 /* Calculate feedback divider. */ 1784 fbdiv = freq * postdiv1 * postdiv2 * refdiv / 24000000; 1785 1786 /* 1787 * Select slow mode to guarantee a stable clock while we're 1788 * adjusting the PLL. 1789 */ 1790 HWRITE4(sc, RK3328_CRU_CRU_MODE, 1791 (RK3328_CRU_CRU_MODE_MASK << 16 | 1792 RK3328_CRU_CRU_MODE_SLOW) << mode_shift); 1793 1794 /* Set PLL rate. */ 1795 HWRITE4(sc, base + 0x0000, 1796 RK3328_CRU_PLL_POSTDIV1_MASK << 16 | 1797 postdiv1 << RK3328_CRU_PLL_POSTDIV1_SHIFT | 1798 RK3328_CRU_PLL_FBDIV_MASK << 16 | 1799 fbdiv << RK3328_CRU_PLL_FBDIV_SHIFT); 1800 HWRITE4(sc, base + 0x0004, 1801 RK3328_CRU_PLL_DSMPD << 16 | RK3328_CRU_PLL_DSMPD | 1802 RK3328_CRU_PLL_POSTDIV2_MASK << 16 | 1803 postdiv2 << RK3328_CRU_PLL_POSTDIV2_SHIFT | 1804 RK3328_CRU_PLL_REFDIV_MASK << 16 | 1805 refdiv << RK3328_CRU_PLL_REFDIV_SHIFT); 1806 1807 /* Wait for PLL to stabilize. */ 1808 while ((HREAD4(sc, base + 0x0004) & RK3328_CRU_PLL_PLL_LOCK) == 0) 1809 delay(10); 1810 1811 /* Switch back to normal mode. */ 1812 HWRITE4(sc, RK3328_CRU_CRU_MODE, 1813 (RK3328_CRU_CRU_MODE_MASK << 16 | 1814 RK3328_CRU_CRU_MODE_NORMAL) << mode_shift); 1815 1816 return 0; 1817 } 1818 1819 int 1820 rk3328_set_frac_pll(struct rkclock_softc *sc, bus_size_t base, uint32_t freq) 1821 { 1822 uint32_t fbdiv, postdiv1, postdiv2, refdiv, fracdiv; 1823 int mode_shift = -1; 1824 uint32_t reg; 1825 1826 switch (base) { 1827 case RK3328_CRU_APLL_CON(0): 1828 mode_shift = 0; 1829 break; 1830 case RK3328_CRU_DPLL_CON(0): 1831 mode_shift = 4; 1832 break; 1833 case RK3328_CRU_CPLL_CON(0): 1834 mode_shift = 8; 1835 break; 1836 case RK3328_CRU_GPLL_CON(0): 1837 mode_shift = 12; 1838 break; 1839 case RK3328_CRU_NPLL_CON(0): 1840 mode_shift = 1; 1841 break; 1842 } 1843 KASSERT(mode_shift != -1); 1844 1845 /* 1846 * It is not clear whether all combinations of the clock 1847 * dividers result in a stable clock. Therefore this function 1848 * only supports a limited set of PLL clock rates. This set 1849 * set covers all the fractional PLL frequencies supported by 1850 * the Linux kernel. 1851 */ 1852 switch (freq) { 1853 case 1016064000U: 1854 postdiv1 = postdiv2 = 1; refdiv = 3; fracdiv = 134217; 1855 break; 1856 case 983040000U: 1857 postdiv1 = postdiv2 = 1; refdiv = 24; fracdiv = 671088; 1858 break; 1859 case 491520000U: 1860 postdiv1 = 2; postdiv2 = 1; refdiv = 24; fracdiv = 671088; 1861 break; 1862 case 61440000U: 1863 postdiv1 = 7; postdiv2 = 2; refdiv = 6; fracdiv = 671088; 1864 break; 1865 case 56448000U: 1866 postdiv1 = postdiv2 = 4; refdiv = 12; fracdiv = 9797894; 1867 break; 1868 case 40960000U: 1869 postdiv1 = 4; postdiv2 = 5; refdiv = 12; fracdiv = 10066239; 1870 break; 1871 default: 1872 printf("%s: %u Hz\n", __func__, freq); 1873 return -1; 1874 } 1875 1876 /* Calculate feedback divider. */ 1877 fbdiv = (uint64_t)freq * postdiv1 * postdiv2 * refdiv / 24000000; 1878 1879 /* 1880 * Select slow mode to guarantee a stable clock while we're 1881 * adjusting the PLL. 1882 */ 1883 HWRITE4(sc, RK3328_CRU_CRU_MODE, 1884 (RK3328_CRU_CRU_MODE_MASK << 16 | 1885 RK3328_CRU_CRU_MODE_SLOW) << mode_shift); 1886 1887 /* Set PLL rate. */ 1888 HWRITE4(sc, base + 0x0000, 1889 RK3328_CRU_PLL_POSTDIV1_MASK << 16 | 1890 postdiv1 << RK3328_CRU_PLL_POSTDIV1_SHIFT | 1891 RK3328_CRU_PLL_FBDIV_MASK << 16 | 1892 fbdiv << RK3328_CRU_PLL_FBDIV_SHIFT); 1893 HWRITE4(sc, base + 0x0004, 1894 RK3328_CRU_PLL_DSMPD << 16 | 1895 RK3328_CRU_PLL_POSTDIV2_MASK << 16 | 1896 postdiv2 << RK3328_CRU_PLL_POSTDIV2_SHIFT | 1897 RK3328_CRU_PLL_REFDIV_MASK << 16 | 1898 refdiv << RK3328_CRU_PLL_REFDIV_SHIFT); 1899 reg = HREAD4(sc, base + 0x0008); 1900 reg &= ~RK3328_CRU_PLL_FRACDIV_MASK; 1901 reg |= fracdiv << RK3328_CRU_PLL_FRACDIV_SHIFT; 1902 HWRITE4(sc, base + 0x0008, reg); 1903 1904 /* Wait for PLL to stabilize. */ 1905 while ((HREAD4(sc, base + 0x0004) & RK3328_CRU_PLL_PLL_LOCK) == 0) 1906 delay(10); 1907 1908 /* Switch back to normal mode. */ 1909 HWRITE4(sc, RK3328_CRU_CRU_MODE, 1910 (RK3328_CRU_CRU_MODE_MASK << 16 | 1911 RK3328_CRU_CRU_MODE_NORMAL) << mode_shift); 1912 1913 return 0; 1914 } 1915 1916 uint32_t 1917 rk3328_get_frequency(void *cookie, uint32_t *cells) 1918 { 1919 struct rkclock_softc *sc = cookie; 1920 uint32_t idx = cells[0]; 1921 uint32_t reg; 1922 1923 switch (idx) { 1924 case RK3328_PLL_APLL: 1925 return rk3328_get_pll(sc, RK3328_CRU_APLL_CON(0)); 1926 break; 1927 case RK3328_PLL_DPLL: 1928 return rk3328_get_pll(sc, RK3328_CRU_DPLL_CON(0)); 1929 break; 1930 case RK3328_PLL_CPLL: 1931 return rk3328_get_pll(sc, RK3328_CRU_CPLL_CON(0)); 1932 break; 1933 case RK3328_PLL_GPLL: 1934 return rk3328_get_pll(sc, RK3328_CRU_GPLL_CON(0)); 1935 break; 1936 case RK3328_PLL_NPLL: 1937 return rk3328_get_pll(sc, RK3328_CRU_NPLL_CON(0)); 1938 break; 1939 case RK3328_ARMCLK: 1940 return rk3328_get_armclk(sc); 1941 case RK3328_XIN24M: 1942 return 24000000; 1943 case RK3328_GMAC_CLKIN: 1944 return 125000000; 1945 /* 1946 * XXX The HDMIPHY and USB480M clocks are external. Returning 1947 * zero here will cause them to be ignored for reparenting 1948 * purposes. 1949 */ 1950 case RK3328_HDMIPHY: 1951 return 0; 1952 case RK3328_USB480M: 1953 return 0; 1954 case RK3328_CLK_MAC2IO: 1955 reg = regmap_read_4(sc->sc_grf, RK3328_GRF_MAC_CON1); 1956 if (reg & RK3328_GRF_GMAC2IO_RMII_EXTCLK_SEL) 1957 idx = RK3328_GMAC_CLKIN; 1958 else 1959 idx = RK3328_CLK_MAC2IO_SRC; 1960 return rk3328_get_frequency(sc, &idx); 1961 default: 1962 break; 1963 } 1964 1965 return rkclock_get_frequency(sc, idx); 1966 } 1967 1968 int 1969 rk3328_set_frequency(void *cookie, uint32_t *cells, uint32_t freq) 1970 { 1971 struct rkclock_softc *sc = cookie; 1972 uint32_t idx = cells[0]; 1973 uint32_t reg, mux; 1974 1975 switch (idx) { 1976 case RK3328_PLL_APLL: 1977 return rk3328_set_frac_pll(sc, RK3328_CRU_APLL_CON(0), freq); 1978 case RK3328_PLL_DPLL: 1979 return rk3328_set_pll(sc, RK3328_CRU_DPLL_CON(0), freq); 1980 case RK3328_PLL_CPLL: 1981 return rk3328_set_pll(sc, RK3328_CRU_CPLL_CON(0), freq); 1982 case RK3328_PLL_GPLL: 1983 return rk3328_set_frac_pll(sc, RK3328_CRU_GPLL_CON(0), freq); 1984 case RK3328_PLL_NPLL: 1985 return rk3328_set_pll(sc, RK3328_CRU_NPLL_CON(0), freq); 1986 case RK3328_ARMCLK: 1987 return rk3328_set_armclk(sc, freq); 1988 case RK3328_CLK_UART0: 1989 case RK3328_CLK_UART1: 1990 case RK3328_CLK_UART2: 1991 if (freq == rk3328_get_frequency(sc, &idx)) 1992 return 0; 1993 break; 1994 case RK3328_DCLK_LCDC: 1995 reg = HREAD4(sc, RK3328_CRU_CLKSEL_CON(40)); 1996 mux = (reg & RK3328_CRU_VOP_DCLK_SRC_SEL_MASK) >> 1997 RK3328_CRU_VOP_DCLK_SRC_SEL_SHIFT; 1998 idx = (mux == 0) ? RK3328_HDMIPHY : RK3328_DCLK_LCDC_SRC; 1999 return rk3328_set_frequency(sc, &idx, freq); 2000 case RK3328_HCLK_CRYPTO_SLV: 2001 idx = RK3328_HCLK_BUS_PRE; 2002 return rk3328_set_frequency(sc, &idx, freq); 2003 default: 2004 break; 2005 } 2006 2007 return rkclock_set_frequency(sc, idx, freq); 2008 } 2009 2010 int 2011 rk3328_set_parent(void *cookie, uint32_t *cells, uint32_t *pcells) 2012 { 2013 struct rkclock_softc *sc = cookie; 2014 uint32_t idx = cells[0]; 2015 uint32_t parent; 2016 2017 if (pcells[0] == sc->sc_phandle) 2018 parent = pcells[1]; 2019 else { 2020 char name[32]; 2021 int node; 2022 2023 node = OF_getnodebyphandle(pcells[0]); 2024 if (node == 0) 2025 return -1; 2026 name[0] = 0; 2027 OF_getprop(node, "clock-output-names", name, sizeof(name)); 2028 name[sizeof(name) - 1] = 0; 2029 if (strcmp(name, "xin24m") == 0) 2030 parent = RK3328_XIN24M; 2031 else if (strcmp(name, "gmac_clkin") == 0) 2032 parent = RK3328_GMAC_CLKIN; 2033 else 2034 return -1; 2035 } 2036 2037 switch (idx) { 2038 case RK3328_CLK_MAC2IO: 2039 if (parent == RK3328_GMAC_CLKIN) { 2040 regmap_write_4(sc->sc_grf, RK3328_GRF_MAC_CON1, 2041 RK3328_GRF_GMAC2IO_RMII_EXTCLK_SEL << 16 | 2042 RK3328_GRF_GMAC2IO_RMII_EXTCLK_SEL); 2043 } else { 2044 regmap_write_4(sc->sc_grf, RK3328_GRF_MAC_CON1, 2045 RK3328_GRF_GMAC2IO_RMII_EXTCLK_SEL << 16); 2046 } 2047 return 0; 2048 case RK3328_CLK_MAC2IO_EXT: 2049 if (parent == RK3328_GMAC_CLKIN) { 2050 regmap_write_4(sc->sc_grf, RK3328_GRF_SOC_CON4, 2051 RK3328_GRF_GMAC2IO_MAC_CLK_OUTPUT_EN << 16 | 2052 RK3328_GRF_GMAC2IO_MAC_CLK_OUTPUT_EN); 2053 } else { 2054 regmap_write_4(sc->sc_grf, RK3328_GRF_SOC_CON4, 2055 RK3328_GRF_GMAC2IO_MAC_CLK_OUTPUT_EN << 16); 2056 } 2057 return 0; 2058 } 2059 2060 return rkclock_set_parent(sc, idx, parent); 2061 } 2062 2063 void 2064 rk3328_enable(void *cookie, uint32_t *cells, int on) 2065 { 2066 uint32_t idx = cells[0]; 2067 2068 /* 2069 * All clocks are enabled by default, so there is nothing for 2070 * us to do until we start disabling clocks. 2071 */ 2072 if (!on) 2073 printf("%s: 0x%08x\n", __func__, idx); 2074 } 2075 2076 void 2077 rk3328_reset(void *cookie, uint32_t *cells, int on) 2078 { 2079 struct rkclock_softc *sc = cookie; 2080 uint32_t idx = cells[0]; 2081 uint32_t mask = (1 << (idx % 16)); 2082 2083 HWRITE4(sc, RK3328_CRU_SOFTRST_CON(idx / 16), 2084 mask << 16 | (on ? mask : 0)); 2085 } 2086 2087 /* 2088 * Rockchip RK3399 2089 */ 2090 2091 struct rkclock rk3399_clocks[] = { 2092 { 2093 RK3399_CLK_I2C1, RK3399_CRU_CLKSEL_CON(61), 2094 SEL(7, 7), DIV(6, 0), 2095 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 2096 }, 2097 { 2098 RK3399_CLK_I2C2, RK3399_CRU_CLKSEL_CON(62), 2099 SEL(7, 7), DIV(6, 0), 2100 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 2101 }, 2102 { 2103 RK3399_CLK_I2C3, RK3399_CRU_CLKSEL_CON(63), 2104 SEL(7, 7), DIV(6, 0), 2105 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 2106 }, 2107 { 2108 RK3399_CLK_I2C5, RK3399_CRU_CLKSEL_CON(61), 2109 SEL(15, 15), DIV(14, 8), 2110 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 2111 }, 2112 { 2113 RK3399_CLK_I2C6, RK3399_CRU_CLKSEL_CON(62), 2114 SEL(15, 15), DIV(14, 8), 2115 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 2116 }, 2117 { 2118 RK3399_CLK_I2C7, RK3399_CRU_CLKSEL_CON(63), 2119 SEL(15, 15), DIV(14, 8), 2120 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 2121 }, 2122 { 2123 RK3399_CLK_SDMMC, RK3399_CRU_CLKSEL_CON(16), 2124 SEL(10, 8), DIV(6, 0), 2125 { RK3399_PLL_CPLL, RK3399_PLL_GPLL, RK3399_PLL_NPLL, 2126 /* RK3399_PLL_PPLL */ 0, /* RK3399_USB_480M */ 0, 2127 RK3399_XIN24M } 2128 }, 2129 { 2130 RK3399_CLK_SDIO, RK3399_CRU_CLKSEL_CON(15), 2131 SEL(10, 8), DIV(6, 0), 2132 { RK3399_PLL_CPLL, RK3399_PLL_GPLL, RK3399_PLL_NPLL, 2133 /* RK3399_PLL_PPLL */ 0, /* RK3399_USB_480M */ 0, 2134 RK3399_XIN24M } 2135 }, 2136 { 2137 RK3399_CLK_EMMC, RK3399_CRU_CLKSEL_CON(22), 2138 SEL(10, 8), DIV(6, 0), 2139 { RK3399_PLL_CPLL, RK3399_PLL_GPLL, RK3399_PLL_NPLL, 2140 /* RK3399_USB_480M */ 0, RK3399_XIN24M } 2141 }, 2142 { 2143 RK3399_CLK_TSADC, RK3399_CRU_CLKSEL_CON(27), 2144 SEL(15, 15), DIV(9, 0), 2145 { RK3399_XIN24M, RK3399_CLK_32K } 2146 }, 2147 { 2148 RK3399_CLK_UART0, RK3399_CRU_CLKSEL_CON(33), 2149 SEL(9, 8), 0, 2150 { 0, 0, RK3399_XIN24M } 2151 }, 2152 { 2153 RK3399_CLK_UART1, RK3399_CRU_CLKSEL_CON(34), 2154 SEL(9, 8), 0, 2155 { 0, 0, RK3399_XIN24M } 2156 }, 2157 { 2158 RK3399_CLK_UART2, RK3399_CRU_CLKSEL_CON(35), 2159 SEL(9, 8), 0, 2160 { 0, 0, RK3399_XIN24M } 2161 }, 2162 { 2163 RK3399_CLK_UART3, RK3399_CRU_CLKSEL_CON(36), 2164 SEL(9, 8), 0, 2165 { 0, 0, RK3399_XIN24M } 2166 }, 2167 { 2168 RK3399_CLK_I2S0_8CH, RK3399_CRU_CLKSEL_CON(28), 2169 SEL(9, 8), 0, 2170 { RK3399_CLK_I2S0_DIV, RK3399_CLK_I2S0_FRAC, 0, RK3399_XIN12M }, 2171 SET_PARENT 2172 }, 2173 { 2174 RK3399_CLK_I2S1_8CH, RK3399_CRU_CLKSEL_CON(29), 2175 SEL(9, 8), 0, 2176 { RK3399_CLK_I2S1_DIV, RK3399_CLK_I2S1_FRAC, 0, RK3399_XIN12M }, 2177 SET_PARENT 2178 }, 2179 { 2180 RK3399_CLK_I2S2_8CH, RK3399_CRU_CLKSEL_CON(30), 2181 SEL(9, 8), 0, 2182 { RK3399_CLK_I2S2_DIV, RK3399_CLK_I2S2_FRAC, 0, RK3399_XIN12M }, 2183 SET_PARENT 2184 }, 2185 { 2186 RK3399_CLK_I2S_8CH_OUT, RK3399_CRU_CLKSEL_CON(31), 2187 SEL(2, 2), 0, 2188 { RK3399_CLK_I2SOUT_SRC, RK3399_XIN12M }, 2189 SET_PARENT 2190 }, 2191 { 2192 RK3399_CLK_MAC, RK3399_CRU_CLKSEL_CON(20), 2193 SEL(15, 14), DIV(12, 8), 2194 { RK3399_PLL_CPLL, RK3399_PLL_GPLL, RK3399_PLL_NPLL } 2195 }, 2196 { 2197 RK3399_DCLK_VOP0, RK3399_CRU_CLKSEL_CON(49), 2198 SEL(11, 11), 0, 2199 { RK3399_DCLK_VOP0_DIV, RK3399_DCLK_VOP0_FRAC }, 2200 SET_PARENT 2201 }, 2202 { 2203 RK3399_DCLK_VOP1, RK3399_CRU_CLKSEL_CON(50), 2204 SEL(11, 11), 0, 2205 { RK3399_DCLK_VOP1_DIV, RK3399_DCLK_VOP1_FRAC }, 2206 SET_PARENT 2207 }, 2208 { 2209 RK3399_DCLK_VOP0_DIV, RK3399_CRU_CLKSEL_CON(49), 2210 SEL(9, 8), DIV(7, 0), 2211 { RK3399_PLL_VPLL, RK3399_PLL_CPLL, RK3399_PLL_GPLL } 2212 }, 2213 { 2214 RK3399_DCLK_VOP1_DIV, RK3399_CRU_CLKSEL_CON(50), 2215 SEL(9, 8), DIV(7, 0), 2216 { RK3399_PLL_VPLL, RK3399_PLL_CPLL, RK3399_PLL_GPLL } 2217 }, 2218 { 2219 RK3399_ACLK_PERIPH, RK3399_CRU_CLKSEL_CON(14), 2220 SEL(7, 7), DIV(4, 0), 2221 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 2222 }, 2223 { 2224 RK3399_ACLK_PERILP0, RK3399_CRU_CLKSEL_CON(23), 2225 SEL(7, 7), DIV(4, 0), 2226 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 2227 }, 2228 { 2229 RK3399_ACLK_VIO, RK3399_CRU_CLKSEL_CON(42), 2230 SEL(7, 6), DIV(4, 0), 2231 { RK3399_PLL_CPLL, RK3399_PLL_GPLL, /* RK3399_PLL_PPLL */ } 2232 }, 2233 { 2234 RK3399_ACLK_CCI, RK3399_CRU_CLKSEL_CON(5), 2235 SEL(7, 6), DIV(4, 0), 2236 { RK3399_PLL_CPLL, RK3399_PLL_GPLL, RK3399_PLL_NPLL, 2237 RK3399_PLL_VPLL } 2238 }, 2239 { 2240 RK3399_ACLK_VOP0, RK3399_CRU_CLKSEL_CON(47), 2241 SEL(7, 6), DIV(4, 0), 2242 { RK3399_PLL_VPLL, RK3399_PLL_CPLL, RK3399_PLL_GPLL, 2243 RK3399_PLL_NPLL } 2244 }, 2245 { 2246 RK3399_ACLK_VOP1, RK3399_CRU_CLKSEL_CON(48), 2247 SEL(7, 6), DIV(4, 0), 2248 { RK3399_PLL_VPLL, RK3399_PLL_CPLL, RK3399_PLL_GPLL, 2249 RK3399_PLL_NPLL } 2250 }, 2251 { 2252 RK3399_ACLK_HDCP, RK3399_CRU_CLKSEL_CON(42), 2253 SEL(15, 14), DIV(12, 8), 2254 { RK3399_PLL_CPLL, RK3399_PLL_GPLL, /* RK3399_PLL_PPLL */ } 2255 }, 2256 { 2257 RK3399_ACLK_GIC_PRE, RK3399_CRU_CLKSEL_CON(56), 2258 SEL(15, 15), DIV(12, 8), 2259 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 2260 }, 2261 { 2262 RK3399_PCLK_PERIPH, RK3399_CRU_CLKSEL_CON(14), 2263 0, DIV(14, 12), 2264 { RK3399_ACLK_PERIPH } 2265 }, 2266 { 2267 RK3399_PCLK_PERILP0, RK3399_CRU_CLKSEL_CON(23), 2268 0, DIV(14, 12), 2269 { RK3399_ACLK_PERILP0 } 2270 }, 2271 { 2272 RK3399_PCLK_PERILP1, RK3399_CRU_CLKSEL_CON(25), 2273 0, DIV(10, 8), 2274 { RK3399_HCLK_PERILP1 } 2275 }, 2276 { 2277 RK3399_PCLK_DDR, RK3399_CRU_CLKSEL_CON(6), 2278 SEL(15, 15), DIV(12, 8), 2279 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 2280 }, 2281 { 2282 RK3399_HCLK_PERIPH, RK3399_CRU_CLKSEL_CON(14), 2283 0, DIV(9, 8), 2284 { RK3399_ACLK_PERIPH } 2285 }, 2286 { 2287 RK3399_HCLK_PERILP0, RK3399_CRU_CLKSEL_CON(23), 2288 0, DIV(9, 8), 2289 { RK3399_ACLK_PERILP0 } 2290 }, 2291 { 2292 RK3399_HCLK_PERILP1, RK3399_CRU_CLKSEL_CON(25), 2293 SEL(7, 7), DIV(4, 0), 2294 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 2295 }, 2296 { 2297 RK3399_HCLK_SDMMC, RK3399_CRU_CLKSEL_CON(13), 2298 SEL(15, 15), DIV(12, 8), 2299 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 2300 }, 2301 { 2302 RK3399_HCLK_VOP0, RK3399_CRU_CLKSEL_CON(47), 2303 0, DIV(12, 8), 2304 { RK3399_ACLK_VOP0 } 2305 }, 2306 { 2307 RK3399_HCLK_VOP1, RK3399_CRU_CLKSEL_CON(48), 2308 0, DIV(12, 8), 2309 { RK3399_ACLK_VOP1 } 2310 }, 2311 { 2312 RK3399_CLK_I2S0_DIV, RK3399_CRU_CLKSEL_CON(28), 2313 SEL(7, 7), DIV(6, 0), 2314 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 2315 }, 2316 { 2317 RK3399_CLK_I2S1_DIV, RK3399_CRU_CLKSEL_CON(29), 2318 SEL(7, 7), DIV(6, 0), 2319 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 2320 }, 2321 { 2322 RK3399_CLK_I2S2_DIV, RK3399_CRU_CLKSEL_CON(30), 2323 SEL(7, 7), DIV(6, 0), 2324 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 2325 }, 2326 { 2327 RK3399_CLK_I2SOUT_SRC, RK3399_CRU_CLKSEL_CON(31), 2328 SEL(1, 0), 0, 2329 { RK3399_CLK_I2S0_8CH, RK3399_CLK_I2S1_8CH, 2330 RK3399_CLK_I2S2_8CH }, 2331 SET_PARENT 2332 }, 2333 { 2334 /* Sentinel */ 2335 } 2336 }; 2337 2338 /* Some of our parent clocks live in the PMUCRU. */ 2339 struct rkclock_softc *rk3399_pmucru_sc; 2340 2341 void 2342 rk3399_init(struct rkclock_softc *sc) 2343 { 2344 int i; 2345 2346 /* PMUCRU instance should attach before us. */ 2347 KASSERT(rk3399_pmucru_sc != NULL); 2348 2349 /* 2350 * The U-Boot shipped on the Theobroma Systems RK3399-Q7 2351 * module is buggy and sets the parent of the clock for the 2352 * "big" cluster to LPLL. Undo that mistake here such that 2353 * the clocks of both clusters are independent. 2354 */ 2355 HWRITE4(sc, RK3399_CRU_CLKSEL_CON(2), 2356 RK3399_CRU_CORE_PLL_SEL_MASK << 16 | 2357 RK3399_CRU_CORE_PLL_SEL_BPLL); 2358 2359 /* The code below assumes all clocks are enabled. Check this!. */ 2360 for (i = 0; i <= 34; i++) { 2361 if (HREAD4(sc, RK3399_CRU_CLKGATE_CON(i)) != 0x00000000) { 2362 printf("CRU_CLKGATE_CON%d: 0x%08x\n", i, 2363 HREAD4(sc, RK3399_CRU_CLKGATE_CON(i))); 2364 } 2365 } 2366 2367 sc->sc_clocks = rk3399_clocks; 2368 } 2369 2370 uint32_t 2371 rk3399_get_pll(struct rkclock_softc *sc, bus_size_t base) 2372 { 2373 uint32_t fbdiv, postdiv1, postdiv2, refdiv; 2374 uint32_t pll_work_mode; 2375 uint32_t reg; 2376 2377 reg = HREAD4(sc, base + 0x000c); 2378 pll_work_mode = reg & RK3399_CRU_PLL_PLL_WORK_MODE_MASK; 2379 if (pll_work_mode == RK3399_CRU_PLL_PLL_WORK_MODE_SLOW) 2380 return 24000000; 2381 if (pll_work_mode == RK3399_CRU_PLL_PLL_WORK_MODE_DEEP_SLOW) 2382 return 32768; 2383 2384 reg = HREAD4(sc, base + 0x0000); 2385 fbdiv = (reg & RK3399_CRU_PLL_FBDIV_MASK) >> 2386 RK3399_CRU_PLL_FBDIV_SHIFT; 2387 reg = HREAD4(sc, base + 0x0004); 2388 postdiv2 = (reg & RK3399_CRU_PLL_POSTDIV2_MASK) >> 2389 RK3399_CRU_PLL_POSTDIV2_SHIFT; 2390 postdiv1 = (reg & RK3399_CRU_PLL_POSTDIV1_MASK) >> 2391 RK3399_CRU_PLL_POSTDIV1_SHIFT; 2392 refdiv = (reg & RK3399_CRU_PLL_REFDIV_MASK) >> 2393 RK3399_CRU_PLL_REFDIV_SHIFT; 2394 return 24000000ULL * fbdiv / refdiv / postdiv1 / postdiv2; 2395 } 2396 2397 int 2398 rk3399_set_pll(struct rkclock_softc *sc, bus_size_t base, uint32_t freq) 2399 { 2400 uint32_t fbdiv, postdiv1, postdiv2, refdiv; 2401 2402 /* 2403 * It is not clear whether all combinations of the clock 2404 * dividers result in a stable clock. Therefore this function 2405 * only supports a limited set of PLL clock rates. For now 2406 * this set covers all the CPU frequencies supported by the 2407 * Linux kernel. 2408 */ 2409 switch (freq) { 2410 case 2208000000U: 2411 case 2184000000U: 2412 case 2088000000U: 2413 case 2040000000U: 2414 case 2016000000U: 2415 case 1992000000U: 2416 case 1896000000U: 2417 case 1800000000U: 2418 case 1704000000U: 2419 case 1608000000U: 2420 case 1512000000U: 2421 case 1488000000U: 2422 case 1416000000U: 2423 case 1200000000U: 2424 postdiv1 = postdiv2 = refdiv = 1; 2425 break; 2426 case 1008000000U: 2427 case 816000000U: 2428 case 696000000U: 2429 postdiv1 = 2; postdiv2 = refdiv = 1; 2430 break; 2431 case 676000000U: 2432 postdiv1 = 2; postdiv2 = 1; refdiv = 3; 2433 break; 2434 case 1000000000U: 2435 case 800000000U: 2436 case 600000000U: 2437 postdiv1 = 3; postdiv2 = refdiv = 1; 2438 break; 2439 case 594000000U: 2440 postdiv1 = 4; postdiv2 = refdiv = 1; 2441 break; 2442 case 408000000U: 2443 postdiv1 = postdiv2 = 2; refdiv = 1; 2444 break; 2445 case 297000000U: 2446 case 216000000U: 2447 postdiv1 = 4; postdiv2 = 2; refdiv = 1; 2448 break; 2449 case 148500000U: 2450 case 96000000U: 2451 postdiv1 = postdiv2 = 4; refdiv = 1; 2452 break; 2453 case 74250000U: 2454 postdiv1 = postdiv2 = 4; refdiv = 2; 2455 break; 2456 case 65000000U: 2457 case 54000000U: 2458 case 27000000U: 2459 postdiv1 = 6; postdiv2 = 4; refdiv = 1; 2460 break; 2461 default: 2462 printf("%s: %d Hz\n", __func__, freq); 2463 return -1; 2464 } 2465 2466 /* Calculate feedback divider. */ 2467 fbdiv = freq * postdiv1 * postdiv2 * refdiv / 24000000; 2468 2469 /* 2470 * Select slow mode to guarantee a stable clock while we're 2471 * adjusting the PLL. 2472 */ 2473 HWRITE4(sc, base + 0x000c, 2474 RK3399_CRU_PLL_PLL_WORK_MODE_MASK << 16 | 2475 RK3399_CRU_PLL_PLL_WORK_MODE_SLOW); 2476 2477 /* Set PLL rate. */ 2478 HWRITE4(sc, base + 0x0000, 2479 RK3399_CRU_PLL_FBDIV_MASK << 16 | 2480 fbdiv << RK3399_CRU_PLL_FBDIV_SHIFT); 2481 HWRITE4(sc, base + 0x0004, 2482 RK3399_CRU_PLL_POSTDIV2_MASK << 16 | 2483 postdiv2 << RK3399_CRU_PLL_POSTDIV2_SHIFT | 2484 RK3399_CRU_PLL_POSTDIV1_MASK << 16 | 2485 postdiv1 << RK3399_CRU_PLL_POSTDIV1_SHIFT | 2486 RK3399_CRU_PLL_REFDIV_MASK << 16 | 2487 refdiv << RK3399_CRU_PLL_REFDIV_SHIFT); 2488 2489 /* Wait for PLL to stabilize. */ 2490 while ((HREAD4(sc, base + 0x0008) & RK3399_CRU_PLL_PLL_LOCK) == 0) 2491 delay(10); 2492 2493 /* Switch back to normal mode. */ 2494 HWRITE4(sc, base + 0x000c, 2495 RK3399_CRU_PLL_PLL_WORK_MODE_MASK << 16 | 2496 RK3399_CRU_PLL_PLL_WORK_MODE_NORMAL); 2497 2498 return 0; 2499 } 2500 2501 uint32_t 2502 rk3399_armclk_parent(uint32_t mux) 2503 { 2504 switch (mux) { 2505 case 0: 2506 return RK3399_PLL_ALPLL; 2507 case 1: 2508 return RK3399_PLL_ABPLL; 2509 case 2: 2510 return RK3399_PLL_DPLL; 2511 case 3: 2512 return RK3399_PLL_GPLL; 2513 } 2514 2515 return 0; 2516 } 2517 2518 uint32_t 2519 rk3399_get_armclk(struct rkclock_softc *sc, bus_size_t clksel) 2520 { 2521 uint32_t reg, mux, div_con; 2522 uint32_t idx; 2523 2524 reg = HREAD4(sc, clksel); 2525 mux = (reg & RK3399_CRU_CORE_PLL_SEL_MASK) >> 2526 RK3399_CRU_CORE_PLL_SEL_SHIFT; 2527 div_con = (reg & RK3399_CRU_CLK_CORE_DIV_CON_MASK) >> 2528 RK3399_CRU_CLK_CORE_DIV_CON_SHIFT; 2529 idx = rk3399_armclk_parent(mux); 2530 2531 return rk3399_get_frequency(sc, &idx) / (div_con + 1); 2532 } 2533 2534 int 2535 rk3399_set_armclk(struct rkclock_softc *sc, bus_size_t clksel, uint32_t freq) 2536 { 2537 uint32_t reg, mux; 2538 uint32_t old_freq, div; 2539 uint32_t idx; 2540 2541 old_freq = rk3399_get_armclk(sc, clksel); 2542 if (freq == old_freq) 2543 return 0; 2544 2545 reg = HREAD4(sc, clksel); 2546 mux = (reg & RK3399_CRU_CORE_PLL_SEL_MASK) >> 2547 RK3399_CRU_CORE_PLL_SEL_SHIFT; 2548 idx = rk3399_armclk_parent(mux); 2549 2550 /* Keep the atclk_core and pclk_dbg clocks at or below 200 MHz. */ 2551 div = 1; 2552 while (freq / (div + 1) > 200000000) 2553 div++; 2554 2555 /* When ramping up, set clock dividers first. */ 2556 if (freq > old_freq) { 2557 HWRITE4(sc, clksel, 2558 RK3399_CRU_CLK_CORE_DIV_CON_MASK << 16 | 2559 0 << RK3399_CRU_CLK_CORE_DIV_CON_SHIFT | 2560 RK3399_CRU_ACLKM_CORE_DIV_CON_MASK << 16 | 2561 1 << RK3399_CRU_ACLKM_CORE_DIV_CON_SHIFT); 2562 HWRITE4(sc, clksel + 0x0004, 2563 RK3399_CRU_PCLK_DBG_DIV_CON_MASK << 16 | 2564 div << RK3399_CRU_PCLK_DBG_DIV_CON_SHIFT | 2565 RK3399_CRU_ATCLK_CORE_DIV_CON_MASK << 16 | 2566 div << RK3399_CRU_ATCLK_CORE_DIV_CON_SHIFT); 2567 } 2568 2569 rk3399_set_frequency(sc, &idx, freq); 2570 2571 /* When ramping down, set clock dividers last. */ 2572 if (freq < old_freq) { 2573 HWRITE4(sc, clksel, 2574 RK3399_CRU_CLK_CORE_DIV_CON_MASK << 16 | 2575 0 << RK3399_CRU_CLK_CORE_DIV_CON_SHIFT | 2576 RK3399_CRU_ACLKM_CORE_DIV_CON_MASK << 16 | 2577 1 << RK3399_CRU_ACLKM_CORE_DIV_CON_SHIFT); 2578 HWRITE4(sc, clksel + 0x0004, 2579 RK3399_CRU_PCLK_DBG_DIV_CON_MASK << 16 | 2580 div << RK3399_CRU_PCLK_DBG_DIV_CON_SHIFT | 2581 RK3399_CRU_ATCLK_CORE_DIV_CON_MASK << 16 | 2582 div << RK3399_CRU_ATCLK_CORE_DIV_CON_SHIFT); 2583 } 2584 2585 return 0; 2586 } 2587 2588 uint32_t 2589 rk3399_get_frac(struct rkclock_softc *sc, int parent, bus_size_t base) 2590 { 2591 uint32_t frac; 2592 uint16_t n, d; 2593 2594 frac = HREAD4(sc, base); 2595 n = frac >> 16; 2596 d = frac & 0xffff; 2597 return ((uint64_t)rkclock_get_frequency(sc, parent) * n) / d; 2598 } 2599 2600 int 2601 rk3399_set_frac(struct rkclock_softc *sc, int parent, bus_size_t base, 2602 uint32_t freq) 2603 { 2604 uint32_t n, d; 2605 uint32_t p0, p1, p2; 2606 uint32_t q0, q1, q2; 2607 uint32_t a, tmp; 2608 2609 n = freq; 2610 d = rkclock_get_frequency(sc, parent); 2611 2612 /* 2613 * The denominator needs to be at least 20 times the numerator 2614 * for a stable clock. 2615 */ 2616 if (n == 0 || d == 0 || d < 20 * n) 2617 return -1; 2618 2619 /* 2620 * This is a simplified implementation of the algorithm to 2621 * calculate the best rational approximation using continued 2622 * fractions. 2623 */ 2624 2625 p0 = q1 = 0; 2626 p1 = q0 = 1; 2627 2628 while (d != 0) { 2629 /* 2630 * Calculate next coefficient in the continued 2631 * fraction and keep track of the remainder. 2632 */ 2633 tmp = d; 2634 a = n / d; 2635 d = n % d; 2636 n = tmp; 2637 2638 /* 2639 * Calculate next approximation in the series based on 2640 * the current coefficient. 2641 */ 2642 p2 = p0 + a * p1; 2643 q2 = q0 + a * q1; 2644 2645 /* 2646 * Terminate if we reached the maximum allowed 2647 * denominator. 2648 */ 2649 if (q2 > 0xffff) 2650 break; 2651 2652 p0 = p1; p1 = p2; 2653 q0 = q1; q1 = q2; 2654 } 2655 2656 HWRITE4(sc, base, p1 << 16 | q1); 2657 return 0; 2658 } 2659 2660 uint32_t 2661 rk3399_get_frequency(void *cookie, uint32_t *cells) 2662 { 2663 struct rkclock_softc *sc = cookie; 2664 uint32_t idx = cells[0]; 2665 2666 switch (idx) { 2667 case RK3399_PLL_ALPLL: 2668 return rk3399_get_pll(sc, RK3399_CRU_LPLL_CON(0)); 2669 case RK3399_PLL_ABPLL: 2670 return rk3399_get_pll(sc, RK3399_CRU_BPLL_CON(0)); 2671 case RK3399_PLL_DPLL: 2672 return rk3399_get_pll(sc, RK3399_CRU_DPLL_CON(0)); 2673 case RK3399_PLL_CPLL: 2674 return rk3399_get_pll(sc, RK3399_CRU_CPLL_CON(0)); 2675 case RK3399_PLL_GPLL: 2676 return rk3399_get_pll(sc, RK3399_CRU_GPLL_CON(0)); 2677 case RK3399_PLL_NPLL: 2678 return rk3399_get_pll(sc, RK3399_CRU_NPLL_CON(0)); 2679 case RK3399_PLL_VPLL: 2680 return rk3399_get_pll(sc, RK3399_CRU_VPLL_CON(0)); 2681 case RK3399_ARMCLKL: 2682 return rk3399_get_armclk(sc, RK3399_CRU_CLKSEL_CON(0)); 2683 case RK3399_ARMCLKB: 2684 return rk3399_get_armclk(sc, RK3399_CRU_CLKSEL_CON(2)); 2685 case RK3399_XIN24M: 2686 return 24000000; 2687 case RK3399_CLK_32K: 2688 return 32768; 2689 case RK3399_XIN12M: 2690 return 12000000; 2691 case RK3399_CLK_I2S0_FRAC: 2692 return rk3399_get_frac(sc, RK3399_CLK_I2S0_DIV, 2693 RK3399_CRU_CLKSEL_CON(96)); 2694 case RK3399_CLK_I2S1_FRAC: 2695 return rk3399_get_frac(sc, RK3399_CLK_I2S1_DIV, 2696 RK3399_CRU_CLKSEL_CON(97)); 2697 case RK3399_CLK_I2S2_FRAC: 2698 return rk3399_get_frac(sc, RK3399_CLK_I2S2_DIV, 2699 RK3399_CRU_CLKSEL_CON(98)); 2700 default: 2701 break; 2702 } 2703 2704 return rkclock_get_frequency(sc, idx); 2705 } 2706 2707 int 2708 rk3399_set_frequency(void *cookie, uint32_t *cells, uint32_t freq) 2709 { 2710 struct rkclock_softc *sc = cookie; 2711 uint32_t idx = cells[0]; 2712 2713 switch (idx) { 2714 case RK3399_PLL_ALPLL: 2715 return rk3399_set_pll(sc, RK3399_CRU_LPLL_CON(0), freq); 2716 case RK3399_PLL_ABPLL: 2717 return rk3399_set_pll(sc, RK3399_CRU_BPLL_CON(0), freq); 2718 case RK3399_PLL_CPLL: 2719 return rk3399_set_pll(sc, RK3399_CRU_CPLL_CON(0), freq); 2720 case RK3399_PLL_GPLL: 2721 return rk3399_set_pll(sc, RK3399_CRU_GPLL_CON(0), freq); 2722 case RK3399_PLL_NPLL: 2723 return rk3399_set_pll(sc, RK3399_CRU_NPLL_CON(0), freq); 2724 case RK3399_PLL_VPLL: 2725 return rk3399_set_pll(sc, RK3399_CRU_VPLL_CON(0), freq); 2726 case RK3399_ARMCLKL: 2727 return rk3399_set_armclk(sc, RK3399_CRU_CLKSEL_CON(0), freq); 2728 case RK3399_ARMCLKB: 2729 return rk3399_set_armclk(sc, RK3399_CRU_CLKSEL_CON(2), freq); 2730 case RK3399_CLK_I2S0_8CH: 2731 rkclock_set_parent(sc, idx, RK3399_CLK_I2S0_FRAC); 2732 return rkclock_set_frequency(sc, idx, freq); 2733 case RK3399_CLK_I2S1_8CH: 2734 rkclock_set_parent(sc, idx, RK3399_CLK_I2S1_FRAC); 2735 return rkclock_set_frequency(sc, idx, freq); 2736 case RK3399_CLK_I2S2_8CH: 2737 rkclock_set_parent(sc, idx, RK3399_CLK_I2S2_FRAC); 2738 return rkclock_set_frequency(sc, idx, freq); 2739 case RK3399_XIN12M: 2740 if (freq / (1000 * 1000) != 12) 2741 return -1; 2742 return 0; 2743 case RK3399_CLK_I2S0_FRAC: 2744 return rk3399_set_frac(sc, RK3399_CLK_I2S0_DIV, 2745 RK3399_CRU_CLKSEL_CON(96), freq); 2746 case RK3399_CLK_I2S1_FRAC: 2747 return rk3399_set_frac(sc, RK3399_CLK_I2S1_DIV, 2748 RK3399_CRU_CLKSEL_CON(97), freq); 2749 case RK3399_CLK_I2S2_FRAC: 2750 return rk3399_set_frac(sc, RK3399_CLK_I2S2_DIV, 2751 RK3399_CRU_CLKSEL_CON(98), freq); 2752 default: 2753 break; 2754 } 2755 2756 return rkclock_set_frequency(sc, idx, freq); 2757 } 2758 2759 void 2760 rk3399_enable(void *cookie, uint32_t *cells, int on) 2761 { 2762 uint32_t idx = cells[0]; 2763 2764 /* 2765 * All clocks are enabled by default, so there is nothing for 2766 * us to do until we start disabling clocks. 2767 */ 2768 if (!on) 2769 printf("%s: 0x%08x\n", __func__, idx); 2770 } 2771 2772 void 2773 rk3399_reset(void *cookie, uint32_t *cells, int on) 2774 { 2775 struct rkclock_softc *sc = cookie; 2776 uint32_t idx = cells[0]; 2777 uint32_t mask = (1 << (idx % 16)); 2778 2779 HWRITE4(sc, RK3399_CRU_SOFTRST_CON(idx / 16), 2780 mask << 16 | (on ? mask : 0)); 2781 } 2782 2783 /* PMUCRU */ 2784 2785 struct rkclock rk3399_pmu_clocks[] = { 2786 { 2787 RK3399_CLK_I2C0, RK3399_PMUCRU_CLKSEL_CON(2), 2788 0, DIV(6, 0), 2789 { RK3399_PLL_PPLL } 2790 }, 2791 { 2792 RK3399_CLK_I2C4, RK3399_PMUCRU_CLKSEL_CON(3), 2793 0, DIV(6, 0), 2794 { RK3399_PLL_PPLL } 2795 }, 2796 { 2797 RK3399_CLK_I2C8, RK3399_PMUCRU_CLKSEL_CON(2), 2798 0, DIV(14, 8), 2799 { RK3399_PLL_PPLL } 2800 }, 2801 { 2802 RK3399_PCLK_RKPWM, RK3399_PMUCRU_CLKSEL_CON(0), 2803 0, DIV(6, 0), 2804 { RK3399_PLL_PPLL } 2805 }, 2806 { 2807 /* Sentinel */ 2808 } 2809 }; 2810 2811 void 2812 rk3399_pmu_init(struct rkclock_softc *sc) 2813 { 2814 sc->sc_clocks = rk3399_pmu_clocks; 2815 rk3399_pmucru_sc = sc; 2816 } 2817 2818 uint32_t 2819 rk3399_pmu_get_frequency(void *cookie, uint32_t *cells) 2820 { 2821 struct rkclock_softc *sc = cookie; 2822 uint32_t idx = cells[0]; 2823 2824 switch (idx) { 2825 case RK3399_PLL_PPLL: 2826 return rk3399_get_pll(sc, RK3399_PMUCRU_PPLL_CON(0)); 2827 default: 2828 break; 2829 } 2830 2831 return rkclock_get_frequency(sc, idx); 2832 } 2833 2834 int 2835 rk3399_pmu_set_frequency(void *cookie, uint32_t *cells, uint32_t freq) 2836 { 2837 struct rkclock_softc *sc = cookie; 2838 uint32_t idx = cells[0]; 2839 2840 switch (idx) { 2841 case RK3399_PLL_PPLL: 2842 return rk3399_set_pll(sc, RK3399_PMUCRU_PPLL_CON(0), freq); 2843 break; 2844 default: 2845 break; 2846 } 2847 2848 return rkclock_set_frequency(sc, idx, freq); 2849 } 2850 2851 void 2852 rk3399_pmu_enable(void *cookie, uint32_t *cells, int on) 2853 { 2854 uint32_t idx = cells[0]; 2855 2856 switch (idx) { 2857 case RK3399_CLK_I2C0: 2858 case RK3399_CLK_I2C4: 2859 case RK3399_CLK_I2C8: 2860 case RK3399_PCLK_I2C0: 2861 case RK3399_PCLK_I2C4: 2862 case RK3399_PCLK_I2C8: 2863 case RK3399_PCLK_RKPWM: 2864 /* Enabled by default. */ 2865 break; 2866 default: 2867 printf("%s: 0x%08x\n", __func__, idx); 2868 break; 2869 } 2870 } 2871 2872 void 2873 rk3399_pmu_reset(void *cookie, uint32_t *cells, int on) 2874 { 2875 uint32_t idx = cells[0]; 2876 2877 printf("%s: 0x%08x\n", __func__, idx); 2878 } 2879