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