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