1 /* $OpenBSD: rkclock.c,v 1.46 2019/09/20 20:45:28 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 || clk->div_mask == 0) { 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 } 424 425 /* 426 * Start out with the current parent. This prevents 427 * unecessary switching to a different parent. 428 */ 429 best_freq = rkclock_freq(sc, clk, mux, freq); 430 best_mux = mux; 431 432 /* 433 * Find the parent that allows configuration of a frequency 434 * closest to the target frequency. 435 */ 436 if ((clk->flags & FIXED_PARENT) == 0) { 437 for (i = 0; i < nitems(clk->parents); i++) { 438 if (clk->parents[i] == 0) 439 continue; 440 f = rkclock_freq(sc, clk, i, freq); 441 if ((f > best_freq && f <= freq) || 442 (f < best_freq && f >= freq)) { 443 best_freq = f; 444 best_mux = i; 445 } 446 } 447 } 448 449 div_con = rkclock_div_con(sc, clk, best_mux, freq); 450 div_shift = ffs(clk->div_mask) - 1; 451 HWRITE4(sc, clk->reg, 452 clk->sel_mask << 16 | best_mux << sel_shift | 453 clk->div_mask << 16 | div_con << div_shift); 454 return 0; 455 } 456 457 int 458 rkclock_set_parent(struct rkclock_softc *sc, uint32_t idx, uint32_t parent) 459 { 460 struct rkclock *clk; 461 uint32_t mux; 462 int shift; 463 464 clk = rkclock_lookup(sc, idx); 465 if (clk == NULL || clk->sel_mask == 0) { 466 printf("%s: 0x%08x\n", __func__, idx); 467 return -1; 468 } 469 470 for (mux = 0; mux < nitems(clk->parents); mux++) { 471 if (clk->parents[mux] == parent) 472 break; 473 } 474 if (mux == nitems(clk->parents) || parent == 0) { 475 printf("%s: 0x%08x parent 0x%08x\n", __func__, idx, parent); 476 return -1; 477 } 478 479 shift = ffs(clk->sel_mask) - 1; 480 HWRITE4(sc, clk->reg, clk->sel_mask << 16 | mux << shift); 481 return 0; 482 } 483 484 /* 485 * Rockchip RK3288 486 */ 487 488 struct rkclock rk3288_clocks[] = { 489 { 490 RK3288_CLK_SDMMC, RK3288_CRU_CLKSEL_CON(11), 491 SEL(7, 6), DIV(5, 0), 492 { RK3288_PLL_CPLL, RK3288_PLL_GPLL, RK3288_XIN24M } 493 } 494 }; 495 496 void 497 rk3288_init(struct rkclock_softc *sc) 498 { 499 int node; 500 501 /* 502 * Since the hardware comes up with a really conservative CPU 503 * clock frequency, and U-Boot doesn't set it to a more 504 * reasonable default, try to do so here. These defaults were 505 * chosen assuming that the CPU voltage is at least 1.1 V. 506 * Only do this on the Tinker-RK3288 for now where this is 507 * likely to be true given the default voltages for the 508 * regulators on that board. 509 */ 510 node = OF_finddevice("/"); 511 if (OF_is_compatible(node, "rockchip,rk3288-tinker")) { 512 uint32_t idx; 513 514 /* Run at 1.2 GHz. */ 515 idx = RK3288_ARMCLK; 516 rk3288_set_frequency(sc, &idx, 1200000000); 517 } 518 519 sc->sc_clocks = rk3288_clocks; 520 } 521 522 uint32_t 523 rk3288_get_pll(struct rkclock_softc *sc, bus_size_t base) 524 { 525 uint32_t clkod, clkr, clkf; 526 uint32_t reg; 527 528 reg = HREAD4(sc, base); 529 clkod = (reg & RK3288_CRU_PLL_CLKOD_MASK) >> 530 RK3288_CRU_PLL_CLKOD_SHIFT; 531 clkr = (reg & RK3288_CRU_PLL_CLKR_MASK) >> 532 RK3288_CRU_PLL_CLKR_SHIFT; 533 reg = HREAD4(sc, base + 4); 534 clkf = (reg & RK3288_CRU_PLL_CLKF_MASK) >> 535 RK3288_CRU_PLL_CLKF_SHIFT; 536 return 24000000ULL * (clkf + 1) / (clkr + 1) / (clkod + 1); 537 } 538 539 int 540 rk3288_set_pll(struct rkclock_softc *sc, bus_size_t base, uint32_t freq) 541 { 542 int shift = 4 * (base / RK3288_CRU_CPLL_CON(0)); 543 uint32_t no, nr, nf; 544 545 /* 546 * It is not clear whether all combinations of the clock 547 * dividers result in a stable clock. Therefore this function 548 * only supports a limited set of PLL clock rates. For now 549 * this set covers all the CPU frequencies supported by the 550 * Linux kernel. 551 */ 552 switch (freq) { 553 case 1800000000: 554 case 1704000000: 555 case 1608000000: 556 case 1512000000: 557 case 1488000000: 558 case 1416000000: 559 case 1200000000: 560 nr = no = 1; 561 break; 562 case 1008000000: 563 case 816000000: 564 case 696000000: 565 case 600000000: 566 nr = 1; no = 2; 567 break; 568 case 408000000: 569 case 312000000: 570 nr = 1; no = 4; 571 break; 572 case 216000000: 573 case 126000000: 574 nr = 1; no = 8; 575 break; 576 default: 577 printf("%s: %u Hz\n", __func__, freq); 578 return -1; 579 } 580 581 /* Calculate feedback divider. */ 582 nf = freq * nr * no / 24000000; 583 584 /* 585 * Select slow mode to guarantee a stable clock while we're 586 * adjusting the PLL. 587 */ 588 HWRITE4(sc, RK3288_CRU_MODE_CON, 589 (RK3288_CRU_MODE_PLL_WORK_MODE_MASK << 16 | 590 RK3288_CRU_MODE_PLL_WORK_MODE_SLOW) << shift); 591 592 /* Assert reset. */ 593 HWRITE4(sc, base + 0x000c, 594 RK3288_CRU_PLL_RESET << 16 | RK3288_CRU_PLL_RESET); 595 596 /* Set PLL rate. */ 597 HWRITE4(sc, base + 0x0000, 598 RK3288_CRU_PLL_CLKR_MASK << 16 | 599 (nr - 1) << RK3288_CRU_PLL_CLKR_SHIFT | 600 RK3288_CRU_PLL_CLKOD_MASK << 16 | 601 (no - 1) << RK3288_CRU_PLL_CLKOD_SHIFT); 602 HWRITE4(sc, base + 0x0004, 603 RK3288_CRU_PLL_CLKF_MASK << 16 | 604 (nf - 1) << RK3288_CRU_PLL_CLKF_SHIFT); 605 606 /* Deassert reset and wait. */ 607 HWRITE4(sc, base + 0x000c, 608 RK3288_CRU_PLL_RESET << 16); 609 delay((nr * 500 / 24) + 1); 610 611 /* Switch back to normal mode. */ 612 HWRITE4(sc, RK3288_CRU_MODE_CON, 613 (RK3288_CRU_MODE_PLL_WORK_MODE_MASK << 16 | 614 RK3288_CRU_MODE_PLL_WORK_MODE_NORMAL) << shift); 615 616 return 0; 617 } 618 619 uint32_t 620 rk3288_get_frequency(void *cookie, uint32_t *cells) 621 { 622 struct rkclock_softc *sc = cookie; 623 uint32_t idx = cells[0]; 624 uint32_t reg, mux, div_con, aclk_div_con; 625 626 switch (idx) { 627 case RK3288_PLL_APLL: 628 return rk3288_get_pll(sc, RK3288_CRU_APLL_CON(0)); 629 case RK3288_PLL_CPLL: 630 return rk3288_get_pll(sc, RK3288_CRU_CPLL_CON(0)); 631 case RK3288_PLL_GPLL: 632 return rk3288_get_pll(sc, RK3288_CRU_GPLL_CON(0)); 633 case RK3288_PLL_NPLL: 634 return rk3288_get_pll(sc, RK3288_CRU_NPLL_CON(0)); 635 case RK3288_ARMCLK: 636 reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(0)); 637 mux = (reg >> 15) & 0x1; 638 div_con = (reg >> 8) & 0x1f; 639 idx = (mux == 0) ? RK3288_PLL_APLL : RK3288_PLL_GPLL; 640 return rk3288_get_frequency(sc, &idx) / (div_con + 1); 641 case RK3288_XIN24M: 642 return 24000000; 643 case RK3288_CLK_UART0: 644 reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(13)); 645 mux = (reg >> 8) & 0x3; 646 div_con = reg & 0x7f; 647 if (mux == 2) 648 return 24000000 / (div_con + 1); 649 break; 650 case RK3288_CLK_UART1: 651 reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(14)); 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_UART2: 658 reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(15)); 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_UART3: 665 reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(16)); 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_UART4: 672 reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(3)); 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_MAC: 679 reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(21)); 680 if (reg & 0x10) 681 return 125000000;; 682 mux = (reg >> 0) & 0x3; 683 div_con = (reg >> 8) & 0x1f; 684 switch (mux) { 685 case 0: 686 idx = RK3288_PLL_NPLL; 687 break; 688 case 1: 689 idx = RK3288_PLL_CPLL; 690 break; 691 case 2: 692 idx = RK3288_PLL_GPLL; 693 break; 694 default: 695 return 0; 696 } 697 return rk3288_get_frequency(sc, &idx) / (div_con + 1); 698 case RK3288_PCLK_I2C0: 699 case RK3288_PCLK_I2C2: 700 reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(1)); 701 mux = (reg >> 15) & 0x1; 702 /* pd_bus_pclk_div_con */ 703 div_con = (reg >> 12) & 0x7; 704 if (mux == 1) 705 idx = RK3288_PLL_GPLL; 706 else 707 idx = RK3288_PLL_CPLL; 708 return rk3288_get_frequency(sc, &idx) / (div_con + 1); 709 case RK3288_PCLK_I2C1: 710 case RK3288_PCLK_I2C3: 711 case RK3288_PCLK_I2C4: 712 case RK3288_PCLK_I2C5: 713 reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(10)); 714 mux = (reg >> 15) & 0x1; 715 /* peri_pclk_div_con */ 716 div_con = (reg >> 12) & 0x3; 717 /* peri_aclk_div_con */ 718 aclk_div_con = reg & 0xf; 719 if (mux == 1) 720 idx = RK3288_PLL_GPLL; 721 else 722 idx = RK3288_PLL_CPLL; 723 return (rk3288_get_frequency(sc, &idx) / (aclk_div_con + 1)) >> 724 div_con; 725 default: 726 break; 727 } 728 729 return rkclock_get_frequency(sc, idx); 730 } 731 732 int 733 rk3288_set_frequency(void *cookie, uint32_t *cells, uint32_t freq) 734 { 735 struct rkclock_softc *sc = cookie; 736 uint32_t idx = cells[0]; 737 int error; 738 739 switch (idx) { 740 case RK3288_PLL_APLL: 741 return rk3288_set_pll(sc, RK3288_CRU_APLL_CON(0), freq); 742 case RK3288_ARMCLK: 743 idx = RK3288_PLL_APLL; 744 error = rk3288_set_frequency(sc, &idx, freq); 745 if (error == 0) { 746 HWRITE4(sc, RK3288_CRU_CLKSEL_CON(0), 747 ((1 << 15) | (0x1f << 8)) << 16); 748 } 749 return error; 750 default: 751 break; 752 } 753 754 return rkclock_set_frequency(sc, idx, freq); 755 } 756 757 void 758 rk3288_enable(void *cookie, uint32_t *cells, int on) 759 { 760 uint32_t idx = cells[0]; 761 762 switch (idx) { 763 case RK3288_CLK_SDMMC: 764 case RK3288_CLK_TSADC: 765 case RK3288_CLK_UART0: 766 case RK3288_CLK_UART1: 767 case RK3288_CLK_UART2: 768 case RK3288_CLK_UART3: 769 case RK3288_CLK_UART4: 770 case RK3288_CLK_MAC_RX: 771 case RK3288_CLK_MAC_TX: 772 case RK3288_CLK_SDMMC_DRV: 773 case RK3288_CLK_SDMMC_SAMPLE: 774 case RK3288_CLK_MAC: 775 case RK3288_ACLK_GMAC: 776 case RK3288_PCLK_GMAC: 777 case RK3288_PCLK_I2C0: 778 case RK3288_PCLK_I2C1: 779 case RK3288_PCLK_I2C2: 780 case RK3288_PCLK_I2C3: 781 case RK3288_PCLK_I2C4: 782 case RK3288_PCLK_I2C5: 783 case RK3288_PCLK_TSADC: 784 case RK3288_HCLK_HOST0: 785 case RK3288_HCLK_SDMMC: 786 /* Enabled by default. */ 787 break; 788 default: 789 printf("%s: 0x%08x\n", __func__, idx); 790 break; 791 } 792 } 793 794 void 795 rk3288_reset(void *cookie, uint32_t *cells, int on) 796 { 797 struct rkclock_softc *sc = cookie; 798 uint32_t idx = cells[0]; 799 uint32_t mask = (1 << (idx % 16)); 800 801 HWRITE4(sc, RK3288_CRU_SOFTRST_CON(idx / 16), 802 mask << 16 | (on ? mask : 0)); 803 } 804 805 /* 806 * Rockchip RK3328 807 */ 808 809 struct rkclock rk3328_clocks[] = { 810 { 811 RK3328_CLK_RTC32K, RK3328_CRU_CLKSEL_CON(38), 812 SEL(15, 14), DIV(13, 0), 813 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_XIN24M } 814 }, 815 { 816 RK3328_CLK_SDMMC, RK3328_CRU_CLKSEL_CON(30), 817 SEL(9, 8), DIV(7, 0), 818 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_XIN24M, 819 RK3328_USB480M } 820 }, 821 { 822 RK3328_CLK_SDIO, RK3328_CRU_CLKSEL_CON(31), 823 SEL(9, 8), DIV(7, 0), 824 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_XIN24M, 825 RK3328_USB480M } 826 }, 827 { 828 RK3328_CLK_EMMC, RK3328_CRU_CLKSEL_CON(32), 829 SEL(9, 8), DIV(7, 0), 830 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_XIN24M, 831 RK3328_USB480M } 832 }, 833 { 834 RK3328_CLK_TSADC, RK3328_CRU_CLKSEL_CON(22), 835 0, DIV(9, 0), 836 { RK3328_CLK_24M } 837 }, 838 { 839 RK3328_CLK_UART0, RK3328_CRU_CLKSEL_CON(14), 840 SEL(9, 8), 0, 841 { 0, 0, RK3328_XIN24M, RK3328_XIN24M } 842 }, 843 { 844 RK3328_CLK_UART1, RK3328_CRU_CLKSEL_CON(16), 845 SEL(9, 8), 0, 846 { 0, 0, RK3328_XIN24M, RK3328_XIN24M } 847 }, 848 { 849 RK3328_CLK_UART2, RK3328_CRU_CLKSEL_CON(18), 850 SEL(9, 8), 0, 851 { 0, 0, RK3328_XIN24M, RK3328_XIN24M } 852 }, 853 { 854 RK3328_CLK_WIFI, RK3328_CRU_CLKSEL_CON(52), 855 SEL(7, 6), DIV(5, 0), 856 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_USB480M } 857 }, 858 { 859 RK3328_CLK_I2C0, RK3328_CRU_CLKSEL_CON(34), 860 SEL(7, 7), DIV(6, 0), 861 { RK3328_PLL_CPLL, RK3328_PLL_GPLL } 862 }, 863 { 864 RK3328_CLK_I2C1, RK3328_CRU_CLKSEL_CON(34), 865 SEL(15, 15), DIV(14, 8), 866 { RK3328_PLL_CPLL, RK3328_PLL_GPLL } 867 }, 868 { 869 RK3328_CLK_I2C2, RK3328_CRU_CLKSEL_CON(35), 870 SEL(7, 7), DIV(6, 0), 871 { RK3328_PLL_CPLL, RK3328_PLL_GPLL } 872 }, 873 { 874 RK3328_CLK_I2C3, RK3328_CRU_CLKSEL_CON(35), 875 SEL(15, 15), DIV(14, 8), 876 { RK3328_PLL_CPLL, RK3328_PLL_GPLL } 877 }, 878 { 879 RK3328_CLK_PDM, RK3328_CRU_CLKSEL_CON(20), 880 SEL(15, 14), DIV(12, 8), 881 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_PLL_APLL }, 882 FIXED_PARENT | SET_PARENT 883 }, 884 { 885 RK3328_CLK_VDEC_CABAC, RK3328_CRU_CLKSEL_CON(48), 886 SEL(15, 14), DIV(12, 8), 887 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY, 888 RK3328_USB480M } 889 }, 890 { 891 RK3328_CLK_VDEC_CORE, RK3328_CRU_CLKSEL_CON(49), 892 SEL(7, 6), DIV(4, 0), 893 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY, 894 RK3328_USB480M } 895 }, 896 { 897 RK3328_CLK_VENC_DSP, RK3328_CRU_CLKSEL_CON(52), 898 SEL(15, 14), DIV(12, 8), 899 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY, 900 RK3328_USB480M } 901 }, 902 { 903 RK3328_CLK_VENC_CORE, RK3328_CRU_CLKSEL_CON(51), 904 SEL(15, 14), DIV(12, 8), 905 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY, 906 RK3328_USB480M } 907 }, 908 { 909 RK3328_CLK_TSP, RK3328_CRU_CLKSEL_CON(21), 910 SEL(15, 15), DIV(12, 8), 911 { RK3328_PLL_CPLL, RK3328_PLL_GPLL } 912 }, 913 { 914 RK3328_CLK_MAC2IO_SRC, RK3328_CRU_CLKSEL_CON(27), 915 SEL(7, 7), DIV(4, 0), 916 { RK3328_PLL_CPLL, RK3328_PLL_GPLL } 917 }, 918 { 919 RK3328_DCLK_LCDC, RK3328_CRU_CLKSEL_CON(40), 920 SEL(1, 1), 0, 921 { RK3328_HDMIPHY, RK3328_DCLK_LCDC_SRC } 922 }, 923 { 924 RK3328_ACLK_VOP_PRE, RK3328_CRU_CLKSEL_CON(39), 925 SEL(7, 6), DIV(4, 0), 926 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY, 927 RK3328_USB480M } 928 }, 929 { 930 RK3328_ACLK_RGA_PRE, RK3328_CRU_CLKSEL_CON(36), 931 SEL(15, 14), DIV(12, 8), 932 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY, 933 RK3328_USB480M } 934 }, 935 { 936 RK3328_ACLK_BUS_PRE, RK3328_CRU_CLKSEL_CON(0), 937 SEL(14, 13), DIV(12, 8), 938 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY } 939 }, 940 { 941 RK3328_ACLK_PERI_PRE, RK3328_CRU_CLKSEL_CON(28), 942 SEL(7, 6), DIV(4, 0), 943 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY } 944 }, 945 { 946 RK3328_ACLK_RKVDEC_PRE, RK3328_CRU_CLKSEL_CON(48), 947 SEL(7, 6), DIV(4, 0), 948 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY, 949 RK3328_USB480M } 950 }, 951 { 952 RK3328_ACLK_RKVENC, RK3328_CRU_CLKSEL_CON(51), 953 SEL(7, 6), DIV(4, 0), 954 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY, 955 RK3328_USB480M } 956 }, 957 { 958 RK3328_ACLK_VPU_PRE, RK3328_CRU_CLKSEL_CON(50), 959 SEL(7, 6), DIV(4, 0), 960 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY, 961 RK3328_USB480M } 962 }, 963 { 964 RK3328_ACLK_VIO_PRE, RK3328_CRU_CLKSEL_CON(37), 965 SEL(7, 6), DIV(4, 0), 966 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY, 967 RK3328_USB480M } 968 }, 969 { 970 RK3328_PCLK_BUS_PRE, RK3328_CRU_CLKSEL_CON(1), 971 0, DIV(14, 12), 972 { RK3328_ACLK_BUS_PRE } 973 }, 974 { 975 RK3328_HCLK_BUS_PRE, RK3328_CRU_CLKSEL_CON(1), 976 0, DIV(9, 8), 977 { RK3328_ACLK_BUS_PRE } 978 }, 979 { 980 RK3328_PCLK_PERI, RK3328_CRU_CLKSEL_CON(29), 981 0, DIV(6, 4), 982 { RK3328_ACLK_PERI_PRE } 983 }, 984 { 985 RK3328_HCLK_PERI, RK3328_CRU_CLKSEL_CON(29), 986 0, DIV(1, 0), 987 { RK3328_ACLK_PERI_PRE } 988 }, 989 { 990 RK3328_CLK_24M, RK3328_CRU_CLKSEL_CON(2), 991 0, DIV(12, 8), 992 { RK3328_XIN24M } 993 }, 994 { 995 /* Sentinel */ 996 } 997 }; 998 999 void 1000 rk3328_init(struct rkclock_softc *sc) 1001 { 1002 int i; 1003 1004 /* The code below assumes all clocks are enabled. Check this!. */ 1005 for (i = 0; i <= 28; i++) { 1006 if (HREAD4(sc, RK3328_CRU_CLKGATE_CON(i)) != 0x00000000) { 1007 printf("CRU_CLKGATE_CON%d: 0x%08x\n", i, 1008 HREAD4(sc, RK3328_CRU_CLKGATE_CON(i))); 1009 } 1010 } 1011 1012 sc->sc_clocks = rk3328_clocks; 1013 } 1014 1015 uint32_t 1016 rk3328_armclk_parent(uint32_t mux) 1017 { 1018 switch (mux) { 1019 case 0: 1020 return RK3328_PLL_APLL; 1021 case 1: 1022 return RK3328_PLL_GPLL; 1023 case 2: 1024 return RK3328_PLL_DPLL; 1025 case 3: 1026 return RK3328_PLL_NPLL; 1027 } 1028 1029 return 0; 1030 } 1031 1032 uint32_t 1033 rk3328_get_armclk(struct rkclock_softc *sc) 1034 { 1035 uint32_t reg, mux, div_con; 1036 uint32_t idx; 1037 1038 reg = HREAD4(sc, RK3328_CRU_CLKSEL_CON(0)); 1039 mux = (reg & RK3328_CRU_CORE_CLK_PLL_SEL_MASK) >> 1040 RK3328_CRU_CORE_CLK_PLL_SEL_SHIFT; 1041 div_con = (reg & RK3328_CRU_CLK_CORE_DIV_CON_MASK) >> 1042 RK3328_CRU_CLK_CORE_DIV_CON_SHIFT; 1043 idx = rk3328_armclk_parent(mux); 1044 1045 return rk3328_get_frequency(sc, &idx) / (div_con + 1); 1046 } 1047 1048 int 1049 rk3328_set_armclk(struct rkclock_softc *sc, uint32_t freq) 1050 { 1051 uint32_t reg, mux; 1052 uint32_t old_freq, div; 1053 uint32_t idx; 1054 1055 old_freq = rk3328_get_armclk(sc); 1056 if (freq == old_freq) 1057 return 0; 1058 1059 reg = HREAD4(sc, RK3328_CRU_CLKSEL_CON(0)); 1060 mux = (reg & RK3328_CRU_CORE_CLK_PLL_SEL_MASK) >> 1061 RK3328_CRU_CORE_CLK_PLL_SEL_SHIFT; 1062 1063 /* Keep the pclk_dbg clock at or below 300 MHz. */ 1064 div = 1; 1065 while (freq / (div + 1) > 300000000) 1066 div++; 1067 /* and make sure we use an odd divider. */ 1068 if ((div % 2) == 0) 1069 div++; 1070 1071 /* When ramping up, set clock dividers first. */ 1072 if (freq > old_freq) { 1073 HWRITE4(sc, RK3328_CRU_CLKSEL_CON(0), 1074 RK3328_CRU_CLK_CORE_DIV_CON_MASK << 16 | 1075 0 << RK3328_CRU_CLK_CORE_DIV_CON_SHIFT); 1076 HWRITE4(sc, RK3328_CRU_CLKSEL_CON(1), 1077 RK3328_CRU_ACLK_CORE_DIV_CON_MASK << 16 | 1078 1 << RK3328_CRU_ACLK_CORE_DIV_CON_SHIFT | 1079 RK3328_CRU_CLK_CORE_DBG_DIV_CON_MASK << 16 | 1080 div << RK3328_CRU_CLK_CORE_DBG_DIV_CON_SHIFT); 1081 } 1082 1083 /* We always use NPLL and force the switch below if needed. */ 1084 idx = RK3328_PLL_NPLL; 1085 rk3328_set_frequency(sc, &idx, freq); 1086 1087 /* When ramping down, set clock dividers last. */ 1088 if (freq < old_freq || mux != 3) { 1089 HWRITE4(sc, RK3328_CRU_CLKSEL_CON(0), 1090 RK3328_CRU_CORE_CLK_PLL_SEL_MASK << 16 | 1091 3 << RK3328_CRU_CORE_CLK_PLL_SEL_SHIFT | 1092 RK3328_CRU_CLK_CORE_DIV_CON_MASK << 16 | 1093 0 << RK3328_CRU_CLK_CORE_DIV_CON_SHIFT); 1094 HWRITE4(sc, RK3328_CRU_CLKSEL_CON(1), 1095 RK3328_CRU_ACLK_CORE_DIV_CON_MASK << 16 | 1096 1 << RK3328_CRU_ACLK_CORE_DIV_CON_SHIFT | 1097 RK3328_CRU_CLK_CORE_DBG_DIV_CON_MASK << 16 | 1098 div << RK3328_CRU_CLK_CORE_DBG_DIV_CON_SHIFT); 1099 } 1100 1101 return 0; 1102 } 1103 1104 uint32_t 1105 rk3328_get_pll(struct rkclock_softc *sc, bus_size_t base) 1106 { 1107 uint32_t fbdiv, postdiv1, postdiv2, refdiv; 1108 uint32_t dsmpd, fracdiv; 1109 uint64_t frac = 0; 1110 uint32_t reg; 1111 1112 reg = HREAD4(sc, base + 0x0000); 1113 postdiv1 = (reg & RK3328_CRU_PLL_POSTDIV1_MASK) >> 1114 RK3328_CRU_PLL_POSTDIV1_SHIFT; 1115 fbdiv = (reg & RK3328_CRU_PLL_FBDIV_MASK) >> 1116 RK3328_CRU_PLL_FBDIV_SHIFT; 1117 reg = HREAD4(sc, base + 0x0004); 1118 dsmpd = (reg & RK3328_CRU_PLL_DSMPD); 1119 postdiv2 = (reg & RK3328_CRU_PLL_POSTDIV2_MASK) >> 1120 RK3328_CRU_PLL_POSTDIV2_SHIFT; 1121 refdiv = (reg & RK3328_CRU_PLL_REFDIV_MASK) >> 1122 RK3328_CRU_PLL_REFDIV_SHIFT; 1123 reg = HREAD4(sc, base + 0x0008); 1124 fracdiv = (reg & RK3328_CRU_PLL_FRACDIV_MASK) >> 1125 RK3328_CRU_PLL_FRACDIV_SHIFT; 1126 1127 if (dsmpd == 0) 1128 frac = (24000000ULL * fracdiv / refdiv) >> 24; 1129 return ((24000000ULL * fbdiv / refdiv) + frac) / postdiv1 / postdiv2; 1130 } 1131 1132 int 1133 rk3328_set_pll(struct rkclock_softc *sc, bus_size_t base, uint32_t freq) 1134 { 1135 uint32_t fbdiv, postdiv1, postdiv2, refdiv; 1136 int mode_shift = -1; 1137 1138 switch (base) { 1139 case RK3328_CRU_APLL_CON(0): 1140 mode_shift = 0; 1141 break; 1142 case RK3328_CRU_DPLL_CON(0): 1143 mode_shift = 4; 1144 break; 1145 case RK3328_CRU_CPLL_CON(0): 1146 mode_shift = 8; 1147 break; 1148 case RK3328_CRU_GPLL_CON(0): 1149 mode_shift = 12; 1150 break; 1151 case RK3328_CRU_NPLL_CON(0): 1152 mode_shift = 1; 1153 break; 1154 } 1155 KASSERT(mode_shift != -1); 1156 1157 /* 1158 * It is not clear whether all combinations of the clock 1159 * dividers result in a stable clock. Therefore this function 1160 * only supports a limited set of PLL clock rates. For now 1161 * this set covers all the CPU frequencies supported by the 1162 * Linux kernel. 1163 */ 1164 switch (freq) { 1165 case 1800000000U: 1166 case 1704000000U: 1167 case 1608000000U: 1168 case 1512000000U: 1169 case 1488000000U: 1170 case 1416000000U: 1171 case 1392000000U: 1172 case 1296000000U: 1173 case 1200000000U: 1174 case 1104000000U: 1175 postdiv1 = postdiv2 = refdiv = 1; 1176 break; 1177 case 1008000000U: 1178 case 912000000U: 1179 case 816000000U: 1180 case 696000000U: 1181 postdiv1 = 2; postdiv2 = refdiv = 1; 1182 break; 1183 case 600000000U: 1184 postdiv1 = 3; postdiv2 = refdiv = 1; 1185 break; 1186 case 408000000U: 1187 case 312000000U: 1188 postdiv1 = postdiv2 = 2; refdiv = 1; 1189 break; 1190 case 216000000U: 1191 postdiv1 = 4; postdiv2 = 2; refdiv = 1; 1192 break; 1193 case 96000000U: 1194 postdiv1 = postdiv2 = 4; refdiv = 1; 1195 break; 1196 default: 1197 printf("%s: %u Hz\n", __func__, freq); 1198 return -1; 1199 } 1200 1201 /* Calculate feedback divider. */ 1202 fbdiv = freq * postdiv1 * postdiv2 * refdiv / 24000000; 1203 1204 /* 1205 * Select slow mode to guarantee a stable clock while we're 1206 * adjusting the PLL. 1207 */ 1208 HWRITE4(sc, RK3328_CRU_CRU_MODE, 1209 (RK3328_CRU_CRU_MODE_MASK << 16 | 1210 RK3328_CRU_CRU_MODE_SLOW) << mode_shift); 1211 1212 /* Set PLL rate. */ 1213 HWRITE4(sc, base + 0x0000, 1214 RK3328_CRU_PLL_POSTDIV1_MASK << 16 | 1215 postdiv1 << RK3328_CRU_PLL_POSTDIV1_SHIFT | 1216 RK3328_CRU_PLL_FBDIV_MASK << 16 | 1217 fbdiv << RK3328_CRU_PLL_FBDIV_SHIFT); 1218 HWRITE4(sc, base + 0x0004, 1219 RK3328_CRU_PLL_DSMPD << 16 | RK3328_CRU_PLL_DSMPD | 1220 RK3328_CRU_PLL_POSTDIV2_MASK << 16 | 1221 postdiv2 << RK3328_CRU_PLL_POSTDIV2_SHIFT | 1222 RK3328_CRU_PLL_REFDIV_MASK << 16 | 1223 refdiv << RK3328_CRU_PLL_REFDIV_SHIFT); 1224 1225 /* Wait for PLL to stabilize. */ 1226 while ((HREAD4(sc, base + 0x0004) & RK3328_CRU_PLL_PLL_LOCK) == 0) 1227 delay(10); 1228 1229 /* Switch back to normal mode. */ 1230 HWRITE4(sc, RK3328_CRU_CRU_MODE, 1231 (RK3328_CRU_CRU_MODE_MASK << 16 | 1232 RK3328_CRU_CRU_MODE_NORMAL) << mode_shift); 1233 1234 return 0; 1235 } 1236 1237 int 1238 rk3328_set_frac_pll(struct rkclock_softc *sc, bus_size_t base, uint32_t freq) 1239 { 1240 uint32_t fbdiv, postdiv1, postdiv2, refdiv, fracdiv; 1241 int mode_shift = -1; 1242 uint32_t reg; 1243 1244 switch (base) { 1245 case RK3328_CRU_APLL_CON(0): 1246 mode_shift = 0; 1247 break; 1248 case RK3328_CRU_DPLL_CON(0): 1249 mode_shift = 4; 1250 break; 1251 case RK3328_CRU_CPLL_CON(0): 1252 mode_shift = 8; 1253 break; 1254 case RK3328_CRU_GPLL_CON(0): 1255 mode_shift = 12; 1256 break; 1257 case RK3328_CRU_NPLL_CON(0): 1258 mode_shift = 1; 1259 break; 1260 } 1261 KASSERT(mode_shift != -1); 1262 1263 /* 1264 * It is not clear whether all combinations of the clock 1265 * dividers result in a stable clock. Therefore this function 1266 * only supports a limited set of PLL clock rates. This set 1267 * set covers all the fractional PLL frequencies supported by 1268 * the Linux kernel. 1269 */ 1270 switch (freq) { 1271 case 1016064000U: 1272 postdiv1 = postdiv2 = 1; refdiv = 3; fracdiv = 134217; 1273 break; 1274 case 983040000U: 1275 postdiv1 = postdiv2 = 1; refdiv = 24; fracdiv = 671088; 1276 break; 1277 case 491520000U: 1278 postdiv1 = 2; postdiv2 = 1; refdiv = 24; fracdiv = 671088; 1279 break; 1280 case 61440000U: 1281 postdiv1 = 7; postdiv2 = 2; refdiv = 6; fracdiv = 671088; 1282 break; 1283 case 56448000U: 1284 postdiv1 = postdiv2 = 4; refdiv = 12; fracdiv = 9797894; 1285 break; 1286 case 40960000U: 1287 postdiv1 = 4; postdiv2 = 5; refdiv = 12; fracdiv = 10066239; 1288 break; 1289 default: 1290 printf("%s: %u Hz\n", __func__, freq); 1291 return -1; 1292 } 1293 1294 /* Calculate feedback divider. */ 1295 fbdiv = (uint64_t)freq * postdiv1 * postdiv2 * refdiv / 24000000; 1296 1297 /* 1298 * Select slow mode to guarantee a stable clock while we're 1299 * adjusting the PLL. 1300 */ 1301 HWRITE4(sc, RK3328_CRU_CRU_MODE, 1302 (RK3328_CRU_CRU_MODE_MASK << 16 | 1303 RK3328_CRU_CRU_MODE_SLOW) << mode_shift); 1304 1305 /* Set PLL rate. */ 1306 HWRITE4(sc, base + 0x0000, 1307 RK3328_CRU_PLL_POSTDIV1_MASK << 16 | 1308 postdiv1 << RK3328_CRU_PLL_POSTDIV1_SHIFT | 1309 RK3328_CRU_PLL_FBDIV_MASK << 16 | 1310 fbdiv << RK3328_CRU_PLL_FBDIV_SHIFT); 1311 HWRITE4(sc, base + 0x0004, 1312 RK3328_CRU_PLL_DSMPD << 16 | 1313 RK3328_CRU_PLL_POSTDIV2_MASK << 16 | 1314 postdiv2 << RK3328_CRU_PLL_POSTDIV2_SHIFT | 1315 RK3328_CRU_PLL_REFDIV_MASK << 16 | 1316 refdiv << RK3328_CRU_PLL_REFDIV_SHIFT); 1317 reg = HREAD4(sc, base + 0x0008); 1318 reg &= ~RK3328_CRU_PLL_FRACDIV_MASK; 1319 reg |= fracdiv << RK3328_CRU_PLL_FRACDIV_SHIFT; 1320 HWRITE4(sc, base + 0x0008, reg); 1321 1322 /* Wait for PLL to stabilize. */ 1323 while ((HREAD4(sc, base + 0x0004) & RK3328_CRU_PLL_PLL_LOCK) == 0) 1324 delay(10); 1325 1326 /* Switch back to normal mode. */ 1327 HWRITE4(sc, RK3328_CRU_CRU_MODE, 1328 (RK3328_CRU_CRU_MODE_MASK << 16 | 1329 RK3328_CRU_CRU_MODE_NORMAL) << mode_shift); 1330 1331 return 0; 1332 } 1333 1334 uint32_t 1335 rk3328_get_frequency(void *cookie, uint32_t *cells) 1336 { 1337 struct rkclock_softc *sc = cookie; 1338 uint32_t idx = cells[0]; 1339 uint32_t reg; 1340 1341 switch (idx) { 1342 case RK3328_PLL_APLL: 1343 return rk3328_get_pll(sc, RK3328_CRU_APLL_CON(0)); 1344 break; 1345 case RK3328_PLL_DPLL: 1346 return rk3328_get_pll(sc, RK3328_CRU_DPLL_CON(0)); 1347 break; 1348 case RK3328_PLL_CPLL: 1349 return rk3328_get_pll(sc, RK3328_CRU_CPLL_CON(0)); 1350 break; 1351 case RK3328_PLL_GPLL: 1352 return rk3328_get_pll(sc, RK3328_CRU_GPLL_CON(0)); 1353 break; 1354 case RK3328_PLL_NPLL: 1355 return rk3328_get_pll(sc, RK3328_CRU_NPLL_CON(0)); 1356 break; 1357 case RK3328_ARMCLK: 1358 return rk3328_get_armclk(sc); 1359 case RK3328_XIN24M: 1360 return 24000000; 1361 case RK3328_GMAC_CLKIN: 1362 return 125000000; 1363 /* 1364 * XXX The HDMIPHY and USB480M clocks are external. Returning 1365 * zero here will cause them to be ignored for reparenting 1366 * purposes. 1367 */ 1368 case RK3328_HDMIPHY: 1369 return 0; 1370 case RK3328_USB480M: 1371 return 0; 1372 case RK3328_CLK_MAC2IO: 1373 reg = regmap_read_4(sc->sc_grf, RK3328_GRF_MAC_CON1); 1374 if (reg & RK3328_GRF_GMAC2IO_RMII_EXTCLK_SEL) 1375 idx = RK3328_GMAC_CLKIN; 1376 else 1377 idx = RK3328_CLK_MAC2IO_SRC; 1378 return rk3328_get_frequency(sc, &idx); 1379 default: 1380 break; 1381 } 1382 1383 return rkclock_get_frequency(sc, idx); 1384 } 1385 1386 int 1387 rk3328_set_frequency(void *cookie, uint32_t *cells, uint32_t freq) 1388 { 1389 struct rkclock_softc *sc = cookie; 1390 uint32_t idx = cells[0]; 1391 uint32_t reg, mux; 1392 1393 switch (idx) { 1394 case RK3328_PLL_APLL: 1395 return rk3328_set_frac_pll(sc, RK3328_CRU_APLL_CON(0), freq); 1396 case RK3328_PLL_DPLL: 1397 return rk3328_set_pll(sc, RK3328_CRU_DPLL_CON(0), freq); 1398 case RK3328_PLL_CPLL: 1399 return rk3328_set_pll(sc, RK3328_CRU_CPLL_CON(0), freq); 1400 case RK3328_PLL_GPLL: 1401 return rk3328_set_frac_pll(sc, RK3328_CRU_GPLL_CON(0), freq); 1402 case RK3328_PLL_NPLL: 1403 return rk3328_set_pll(sc, RK3328_CRU_NPLL_CON(0), freq); 1404 case RK3328_ARMCLK: 1405 return rk3328_set_armclk(sc, freq); 1406 case RK3328_CLK_UART0: 1407 case RK3328_CLK_UART1: 1408 case RK3328_CLK_UART2: 1409 if (freq == rk3328_get_frequency(sc, &idx)) 1410 return 0; 1411 break; 1412 case RK3328_DCLK_LCDC: 1413 reg = HREAD4(sc, RK3328_CRU_CLKSEL_CON(40)); 1414 mux = (reg & RK3328_CRU_VOP_DCLK_SRC_SEL_MASK) >> 1415 RK3328_CRU_VOP_DCLK_SRC_SEL_SHIFT; 1416 idx = (mux == 0) ? RK3328_HDMIPHY : RK3328_DCLK_LCDC_SRC; 1417 return rk3328_set_frequency(sc, &idx, freq); 1418 default: 1419 break; 1420 } 1421 1422 return rkclock_set_frequency(sc, idx, freq); 1423 } 1424 1425 int 1426 rk3328_set_parent(void *cookie, uint32_t *cells, uint32_t *pcells) 1427 { 1428 struct rkclock_softc *sc = cookie; 1429 uint32_t idx = cells[0]; 1430 uint32_t parent; 1431 1432 if (pcells[0] == sc->sc_phandle) 1433 parent = pcells[1]; 1434 else { 1435 char name[32]; 1436 int node; 1437 1438 node = OF_getnodebyphandle(pcells[0]); 1439 if (node == 0) 1440 return -1; 1441 name[0] = 0; 1442 OF_getprop(node, "clock-output-names", name, sizeof(name)); 1443 name[sizeof(name) - 1] = 0; 1444 if (strcmp(name, "xin24m") == 0) 1445 parent = RK3328_XIN24M; 1446 else if (strcmp(name, "gmac_clkin") == 0) 1447 parent = RK3328_GMAC_CLKIN; 1448 else 1449 return -1; 1450 } 1451 1452 switch (idx) { 1453 case RK3328_CLK_MAC2IO: 1454 if (parent == RK3328_GMAC_CLKIN) { 1455 regmap_write_4(sc->sc_grf, RK3328_GRF_MAC_CON1, 1456 RK3328_GRF_GMAC2IO_RMII_EXTCLK_SEL << 16 | 1457 RK3328_GRF_GMAC2IO_RMII_EXTCLK_SEL); 1458 } else { 1459 regmap_write_4(sc->sc_grf, RK3328_GRF_MAC_CON1, 1460 RK3328_GRF_GMAC2IO_RMII_EXTCLK_SEL << 16); 1461 } 1462 return 0; 1463 case RK3328_CLK_MAC2IO_EXT: 1464 if (parent == RK3328_GMAC_CLKIN) { 1465 regmap_write_4(sc->sc_grf, RK3328_GRF_SOC_CON4, 1466 RK3328_GRF_GMAC2IO_MAC_CLK_OUTPUT_EN << 16 | 1467 RK3328_GRF_GMAC2IO_MAC_CLK_OUTPUT_EN); 1468 } else { 1469 regmap_write_4(sc->sc_grf, RK3328_GRF_SOC_CON4, 1470 RK3328_GRF_GMAC2IO_MAC_CLK_OUTPUT_EN << 16); 1471 } 1472 return 0; 1473 } 1474 1475 return rkclock_set_parent(sc, idx, parent); 1476 } 1477 1478 void 1479 rk3328_enable(void *cookie, uint32_t *cells, int on) 1480 { 1481 uint32_t idx = cells[0]; 1482 1483 /* 1484 * All clocks are enabled by default, so there is nothing for 1485 * us to do until we start disabling clocks. 1486 */ 1487 if (!on) 1488 printf("%s: 0x%08x\n", __func__, idx); 1489 } 1490 1491 void 1492 rk3328_reset(void *cookie, uint32_t *cells, int on) 1493 { 1494 struct rkclock_softc *sc = cookie; 1495 uint32_t idx = cells[0]; 1496 uint32_t mask = (1 << (idx % 16)); 1497 1498 HWRITE4(sc, RK3328_CRU_SOFTRST_CON(idx / 16), 1499 mask << 16 | (on ? mask : 0)); 1500 } 1501 1502 /* 1503 * Rockchip RK3399 1504 */ 1505 1506 struct rkclock rk3399_clocks[] = { 1507 { 1508 RK3399_CLK_I2C1, RK3399_CRU_CLKSEL_CON(61), 1509 SEL(7, 7), DIV(6, 0), 1510 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 1511 }, 1512 { 1513 RK3399_CLK_I2C2, RK3399_CRU_CLKSEL_CON(62), 1514 SEL(7, 7), DIV(6, 0), 1515 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 1516 }, 1517 { 1518 RK3399_CLK_I2C3, RK3399_CRU_CLKSEL_CON(63), 1519 SEL(7, 7), DIV(6, 0), 1520 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 1521 }, 1522 { 1523 RK3399_CLK_I2C5, RK3399_CRU_CLKSEL_CON(61), 1524 SEL(15, 15), DIV(14, 8), 1525 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 1526 }, 1527 { 1528 RK3399_CLK_I2C6, RK3399_CRU_CLKSEL_CON(62), 1529 SEL(15, 15), DIV(14, 8), 1530 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 1531 }, 1532 { 1533 RK3399_CLK_I2C7, RK3399_CRU_CLKSEL_CON(63), 1534 SEL(15, 15), DIV(14, 8), 1535 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 1536 }, 1537 { 1538 RK3399_CLK_SDMMC, RK3399_CRU_CLKSEL_CON(16), 1539 SEL(10, 8), DIV(6, 0), 1540 { RK3399_PLL_CPLL, RK3399_PLL_GPLL, RK3399_PLL_NPLL, 1541 /* RK3399_PLL_PPLL */ 0, /* RK3399_USB_480M */ 0, 1542 RK3399_XIN24M } 1543 }, 1544 { 1545 RK3399_CLK_SDIO, RK3399_CRU_CLKSEL_CON(15), 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_TSADC, RK3399_CRU_CLKSEL_CON(27), 1553 SEL(15, 15), DIV(9, 0), 1554 { RK3399_XIN24M, RK3399_CLK_32K } 1555 }, 1556 { 1557 RK3399_CLK_UART0, RK3399_CRU_CLKSEL_CON(33), 1558 SEL(9, 8), 0, 1559 { 0, 0, RK3399_XIN24M } 1560 }, 1561 { 1562 RK3399_CLK_UART1, RK3399_CRU_CLKSEL_CON(34), 1563 SEL(9, 8), 0, 1564 { 0, 0, RK3399_XIN24M } 1565 }, 1566 { 1567 RK3399_CLK_UART2, RK3399_CRU_CLKSEL_CON(35), 1568 SEL(9, 8), 0, 1569 { 0, 0, RK3399_XIN24M } 1570 }, 1571 { 1572 RK3399_CLK_UART3, RK3399_CRU_CLKSEL_CON(36), 1573 SEL(9, 8), 0, 1574 { 0, 0, RK3399_XIN24M } 1575 }, 1576 { 1577 RK3399_CLK_MAC, RK3399_CRU_CLKSEL_CON(20), 1578 SEL(15, 14), DIV(12, 8), 1579 { RK3399_PLL_CPLL, RK3399_PLL_GPLL, RK3399_PLL_NPLL } 1580 }, 1581 { 1582 RK3399_ACLK_PERIPH, RK3399_CRU_CLKSEL_CON(14), 1583 SEL(7, 7), DIV(4, 0), 1584 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 1585 }, 1586 { 1587 RK3399_ACLK_PERILP0, RK3399_CRU_CLKSEL_CON(23), 1588 SEL(7, 7), DIV(4, 0), 1589 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 1590 }, 1591 { 1592 RK3399_ACLK_VIO, RK3399_CRU_CLKSEL_CON(42), 1593 SEL(7, 6), DIV(4, 0), 1594 { RK3399_PLL_CPLL, RK3399_PLL_GPLL, /* RK3399_PLL_PPLL */ } 1595 }, 1596 { 1597 RK3399_ACLK_CCI, RK3399_CRU_CLKSEL_CON(5), 1598 SEL(7, 6), DIV(4, 0), 1599 { RK3399_PLL_CPLL, RK3399_PLL_GPLL, RK3399_PLL_NPLL, 1600 RK3399_PLL_VPLL } 1601 }, 1602 { 1603 RK3399_ACLK_HDCP, RK3399_CRU_CLKSEL_CON(42), 1604 SEL(15, 14), DIV(12, 8), 1605 { RK3399_PLL_CPLL, RK3399_PLL_GPLL, /* RK3399_PLL_PPLL */ } 1606 }, 1607 { 1608 RK3399_ACLK_GIC_PRE, RK3399_CRU_CLKSEL_CON(56), 1609 SEL(15, 15), DIV(12, 8), 1610 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 1611 }, 1612 { 1613 RK3399_PCLK_PERIPH, RK3399_CRU_CLKSEL_CON(14), 1614 0, DIV(14, 12), 1615 { RK3399_ACLK_PERIPH } 1616 }, 1617 { 1618 RK3399_PCLK_PERILP0, RK3399_CRU_CLKSEL_CON(23), 1619 0, DIV(14, 12), 1620 { RK3399_ACLK_PERILP0 } 1621 }, 1622 { 1623 RK3399_PCLK_PERILP1, RK3399_CRU_CLKSEL_CON(25), 1624 0, DIV(10, 8), 1625 { RK3399_HCLK_PERILP1 } 1626 }, 1627 { 1628 RK3399_PCLK_DDR, RK3399_CRU_CLKSEL_CON(6), 1629 SEL(15, 15), DIV(12, 8), 1630 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 1631 }, 1632 { 1633 RK3399_HCLK_PERIPH, RK3399_CRU_CLKSEL_CON(14), 1634 0, DIV(9, 8), 1635 { RK3399_ACLK_PERIPH } 1636 }, 1637 { 1638 RK3399_HCLK_PERILP0, RK3399_CRU_CLKSEL_CON(23), 1639 0, DIV(9, 8), 1640 { RK3399_ACLK_PERILP0 } 1641 }, 1642 { 1643 RK3399_HCLK_PERILP1, RK3399_CRU_CLKSEL_CON(25), 1644 SEL(7, 7), DIV(4, 0), 1645 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 1646 }, 1647 { 1648 RK3399_HCLK_SDMMC, RK3399_CRU_CLKSEL_CON(13), 1649 SEL(15, 15), DIV(12, 8), 1650 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 1651 }, 1652 { 1653 /* Sentinel */ 1654 } 1655 }; 1656 1657 /* Some of our parent clocks live in the PMUCRU. */ 1658 struct rkclock_softc *rk3399_pmucru_sc; 1659 1660 void 1661 rk3399_init(struct rkclock_softc *sc) 1662 { 1663 int i; 1664 1665 /* PMUCRU instance should attach before us. */ 1666 KASSERT(rk3399_pmucru_sc != NULL); 1667 1668 /* 1669 * The U-Boot shipped on the Theobroma Systems RK3399-Q7 1670 * module is buggy and sets the parent of the clock for the 1671 * "big" cluster to LPLL. Undo that mistake here such that 1672 * the clocks of both clusters are independent. 1673 */ 1674 HWRITE4(sc, RK3399_CRU_CLKSEL_CON(2), 1675 RK3399_CRU_CORE_PLL_SEL_MASK << 16 | 1676 RK3399_CRU_CORE_PLL_SEL_BPLL); 1677 1678 /* The code below assumes all clocks are enabled. Check this!. */ 1679 for (i = 0; i <= 34; i++) { 1680 if (HREAD4(sc, RK3399_CRU_CLKGATE_CON(i)) != 0x00000000) { 1681 printf("CRU_CLKGATE_CON%d: 0x%08x\n", i, 1682 HREAD4(sc, RK3399_CRU_CLKGATE_CON(i))); 1683 } 1684 } 1685 1686 sc->sc_clocks = rk3399_clocks; 1687 } 1688 1689 uint32_t 1690 rk3399_get_pll(struct rkclock_softc *sc, bus_size_t base) 1691 { 1692 uint32_t fbdiv, postdiv1, postdiv2, refdiv; 1693 uint32_t pll_work_mode; 1694 uint32_t reg; 1695 1696 reg = HREAD4(sc, base + 0x000c); 1697 pll_work_mode = reg & RK3399_CRU_PLL_PLL_WORK_MODE_MASK; 1698 if (pll_work_mode == RK3399_CRU_PLL_PLL_WORK_MODE_SLOW) 1699 return 24000000; 1700 if (pll_work_mode == RK3399_CRU_PLL_PLL_WORK_MODE_DEEP_SLOW) 1701 return 32768; 1702 1703 reg = HREAD4(sc, base + 0x0000); 1704 fbdiv = (reg & RK3399_CRU_PLL_FBDIV_MASK) >> 1705 RK3399_CRU_PLL_FBDIV_SHIFT; 1706 reg = HREAD4(sc, base + 0x0004); 1707 postdiv2 = (reg & RK3399_CRU_PLL_POSTDIV2_MASK) >> 1708 RK3399_CRU_PLL_POSTDIV2_SHIFT; 1709 postdiv1 = (reg & RK3399_CRU_PLL_POSTDIV1_MASK) >> 1710 RK3399_CRU_PLL_POSTDIV1_SHIFT; 1711 refdiv = (reg & RK3399_CRU_PLL_REFDIV_MASK) >> 1712 RK3399_CRU_PLL_REFDIV_SHIFT; 1713 return 24000000ULL * fbdiv / refdiv / postdiv1 / postdiv2; 1714 } 1715 1716 int 1717 rk3399_set_pll(struct rkclock_softc *sc, bus_size_t base, uint32_t freq) 1718 { 1719 uint32_t fbdiv, postdiv1, postdiv2, refdiv; 1720 1721 /* 1722 * It is not clear whether all combinations of the clock 1723 * dividers result in a stable clock. Therefore this function 1724 * only supports a limited set of PLL clock rates. For now 1725 * this set covers all the CPU frequencies supported by the 1726 * Linux kernel. 1727 */ 1728 switch (freq) { 1729 case 2208000000U: 1730 case 2184000000U: 1731 case 2088000000U: 1732 case 2040000000U: 1733 case 2016000000U: 1734 case 1992000000U: 1735 case 1896000000U: 1736 case 1800000000U: 1737 case 1704000000U: 1738 case 1608000000U: 1739 case 1512000000U: 1740 case 1488000000U: 1741 case 1416000000U: 1742 case 1200000000U: 1743 postdiv1 = postdiv2 = refdiv = 1; 1744 break; 1745 case 1008000000U: 1746 case 816000000U: 1747 case 696000000U: 1748 postdiv1 = 2; postdiv2 = refdiv = 1; 1749 break; 1750 case 676000000U: 1751 postdiv1 = 2; postdiv2 = 1; refdiv = 3; 1752 break; 1753 case 1000000000U: 1754 case 800000000U: 1755 case 600000000U: 1756 postdiv1 = 3; postdiv2 = refdiv = 1; 1757 break; 1758 case 594000000U: 1759 postdiv1 = 4; postdiv2 = refdiv = 1; 1760 break; 1761 case 408000000U: 1762 postdiv1 = postdiv2 = 2; refdiv = 1; 1763 break; 1764 case 216000000U: 1765 postdiv1 = 4; postdiv2 = 2; refdiv = 1; 1766 break; 1767 case 96000000U: 1768 postdiv1 = postdiv2 = 4; refdiv = 1; 1769 break; 1770 default: 1771 printf("%s: %d Hz\n", __func__, freq); 1772 return -1; 1773 } 1774 1775 /* Calculate feedback divider. */ 1776 fbdiv = freq * postdiv1 * postdiv2 * refdiv / 24000000; 1777 1778 /* 1779 * Select slow mode to guarantee a stable clock while we're 1780 * adjusting the PLL. 1781 */ 1782 HWRITE4(sc, base + 0x000c, 1783 RK3399_CRU_PLL_PLL_WORK_MODE_MASK << 16 | 1784 RK3399_CRU_PLL_PLL_WORK_MODE_SLOW); 1785 1786 /* Set PLL rate. */ 1787 HWRITE4(sc, base + 0x0000, 1788 RK3399_CRU_PLL_FBDIV_MASK << 16 | 1789 fbdiv << RK3399_CRU_PLL_FBDIV_SHIFT); 1790 HWRITE4(sc, base + 0x0004, 1791 RK3399_CRU_PLL_POSTDIV2_MASK << 16 | 1792 postdiv2 << RK3399_CRU_PLL_POSTDIV2_SHIFT | 1793 RK3399_CRU_PLL_POSTDIV1_MASK << 16 | 1794 postdiv1 << RK3399_CRU_PLL_POSTDIV1_SHIFT | 1795 RK3399_CRU_PLL_REFDIV_MASK << 16 | 1796 refdiv << RK3399_CRU_PLL_REFDIV_SHIFT); 1797 1798 /* Wait for PLL to stabilize. */ 1799 while ((HREAD4(sc, base + 0x0008) & RK3399_CRU_PLL_PLL_LOCK) == 0) 1800 delay(10); 1801 1802 /* Switch back to normal mode. */ 1803 HWRITE4(sc, base + 0x000c, 1804 RK3399_CRU_PLL_PLL_WORK_MODE_MASK << 16 | 1805 RK3399_CRU_PLL_PLL_WORK_MODE_NORMAL); 1806 1807 return 0; 1808 } 1809 1810 uint32_t 1811 rk3399_armclk_parent(uint32_t mux) 1812 { 1813 switch (mux) { 1814 case 0: 1815 return RK3399_PLL_ALPLL; 1816 case 1: 1817 return RK3399_PLL_ABPLL; 1818 case 2: 1819 return RK3399_PLL_DPLL; 1820 case 3: 1821 return RK3399_PLL_GPLL; 1822 } 1823 1824 return 0; 1825 } 1826 1827 uint32_t 1828 rk3399_get_armclk(struct rkclock_softc *sc, bus_size_t clksel) 1829 { 1830 uint32_t reg, mux, div_con; 1831 uint32_t idx; 1832 1833 reg = HREAD4(sc, clksel); 1834 mux = (reg & RK3399_CRU_CORE_PLL_SEL_MASK) >> 1835 RK3399_CRU_CORE_PLL_SEL_SHIFT; 1836 div_con = (reg & RK3399_CRU_CLK_CORE_DIV_CON_MASK) >> 1837 RK3399_CRU_CLK_CORE_DIV_CON_SHIFT; 1838 idx = rk3399_armclk_parent(mux); 1839 1840 return rk3399_get_frequency(sc, &idx) / (div_con + 1); 1841 } 1842 1843 int 1844 rk3399_set_armclk(struct rkclock_softc *sc, bus_size_t clksel, uint32_t freq) 1845 { 1846 uint32_t reg, mux; 1847 uint32_t old_freq, div; 1848 uint32_t idx; 1849 1850 old_freq = rk3399_get_armclk(sc, clksel); 1851 if (freq == old_freq) 1852 return 0; 1853 1854 reg = HREAD4(sc, clksel); 1855 mux = (reg & RK3399_CRU_CORE_PLL_SEL_MASK) >> 1856 RK3399_CRU_CORE_PLL_SEL_SHIFT; 1857 idx = rk3399_armclk_parent(mux); 1858 1859 /* Keep the atclk_core and pclk_dbg clocks at or below 200 MHz. */ 1860 div = 1; 1861 while (freq / (div + 1) > 200000000) 1862 div++; 1863 1864 /* When ramping up, set clock dividers first. */ 1865 if (freq > old_freq) { 1866 HWRITE4(sc, clksel, 1867 RK3399_CRU_CLK_CORE_DIV_CON_MASK << 16 | 1868 0 << RK3399_CRU_CLK_CORE_DIV_CON_SHIFT | 1869 RK3399_CRU_ACLKM_CORE_DIV_CON_MASK << 16 | 1870 1 << RK3399_CRU_ACLKM_CORE_DIV_CON_SHIFT); 1871 HWRITE4(sc, clksel + 0x0004, 1872 RK3399_CRU_PCLK_DBG_DIV_CON_MASK << 16 | 1873 div << RK3399_CRU_PCLK_DBG_DIV_CON_SHIFT | 1874 RK3399_CRU_ATCLK_CORE_DIV_CON_MASK << 16 | 1875 div << RK3399_CRU_ATCLK_CORE_DIV_CON_SHIFT); 1876 } 1877 1878 rk3399_set_frequency(sc, &idx, freq); 1879 1880 /* When ramping down, set clock dividers last. */ 1881 if (freq < old_freq) { 1882 HWRITE4(sc, clksel, 1883 RK3399_CRU_CLK_CORE_DIV_CON_MASK << 16 | 1884 0 << RK3399_CRU_CLK_CORE_DIV_CON_SHIFT | 1885 RK3399_CRU_ACLKM_CORE_DIV_CON_MASK << 16 | 1886 1 << RK3399_CRU_ACLKM_CORE_DIV_CON_SHIFT); 1887 HWRITE4(sc, clksel + 0x0004, 1888 RK3399_CRU_PCLK_DBG_DIV_CON_MASK << 16 | 1889 div << RK3399_CRU_PCLK_DBG_DIV_CON_SHIFT | 1890 RK3399_CRU_ATCLK_CORE_DIV_CON_MASK << 16 | 1891 div << RK3399_CRU_ATCLK_CORE_DIV_CON_SHIFT); 1892 } 1893 1894 return 0; 1895 } 1896 1897 uint32_t 1898 rk3399_get_frequency(void *cookie, uint32_t *cells) 1899 { 1900 struct rkclock_softc *sc = cookie; 1901 uint32_t idx = cells[0]; 1902 1903 switch (idx) { 1904 case RK3399_PLL_ALPLL: 1905 return rk3399_get_pll(sc, RK3399_CRU_LPLL_CON(0)); 1906 case RK3399_PLL_ABPLL: 1907 return rk3399_get_pll(sc, RK3399_CRU_BPLL_CON(0)); 1908 case RK3399_PLL_DPLL: 1909 return rk3399_get_pll(sc, RK3399_CRU_DPLL_CON(0)); 1910 case RK3399_PLL_CPLL: 1911 return rk3399_get_pll(sc, RK3399_CRU_CPLL_CON(0)); 1912 case RK3399_PLL_GPLL: 1913 return rk3399_get_pll(sc, RK3399_CRU_GPLL_CON(0)); 1914 case RK3399_PLL_NPLL: 1915 return rk3399_get_pll(sc, RK3399_CRU_NPLL_CON(0)); 1916 case RK3399_PLL_VPLL: 1917 return rk3399_get_pll(sc, RK3399_CRU_VPLL_CON(0)); 1918 case RK3399_ARMCLKL: 1919 return rk3399_get_armclk(sc, RK3399_CRU_CLKSEL_CON(0)); 1920 case RK3399_ARMCLKB: 1921 return rk3399_get_armclk(sc, RK3399_CRU_CLKSEL_CON(2)); 1922 case RK3399_XIN24M: 1923 return 24000000; 1924 case RK3399_CLK_32K: 1925 return 32768; 1926 default: 1927 break; 1928 } 1929 1930 return rkclock_get_frequency(sc, idx); 1931 } 1932 1933 int 1934 rk3399_set_frequency(void *cookie, uint32_t *cells, uint32_t freq) 1935 { 1936 struct rkclock_softc *sc = cookie; 1937 uint32_t idx = cells[0]; 1938 1939 switch (idx) { 1940 case RK3399_PLL_ALPLL: 1941 return rk3399_set_pll(sc, RK3399_CRU_LPLL_CON(0), freq); 1942 case RK3399_PLL_ABPLL: 1943 return rk3399_set_pll(sc, RK3399_CRU_BPLL_CON(0), freq); 1944 case RK3399_PLL_CPLL: 1945 return rk3399_set_pll(sc, RK3399_CRU_CPLL_CON(0), freq); 1946 case RK3399_PLL_GPLL: 1947 return rk3399_set_pll(sc, RK3399_CRU_GPLL_CON(0), freq); 1948 case RK3399_PLL_NPLL: 1949 return rk3399_set_pll(sc, RK3399_CRU_NPLL_CON(0), freq); 1950 case RK3399_ARMCLKL: 1951 return rk3399_set_armclk(sc, RK3399_CRU_CLKSEL_CON(0), freq); 1952 case RK3399_ARMCLKB: 1953 return rk3399_set_armclk(sc, RK3399_CRU_CLKSEL_CON(2), freq); 1954 default: 1955 break; 1956 } 1957 1958 return rkclock_set_frequency(sc, idx, freq); 1959 } 1960 1961 void 1962 rk3399_enable(void *cookie, uint32_t *cells, int on) 1963 { 1964 uint32_t idx = cells[0]; 1965 1966 /* 1967 * All clocks are enabled by default, so there is nothing for 1968 * us to do until we start disabling clocks. 1969 */ 1970 if (!on) 1971 printf("%s: 0x%08x\n", __func__, idx); 1972 } 1973 1974 void 1975 rk3399_reset(void *cookie, uint32_t *cells, int on) 1976 { 1977 struct rkclock_softc *sc = cookie; 1978 uint32_t idx = cells[0]; 1979 uint32_t mask = (1 << (idx % 16)); 1980 1981 HWRITE4(sc, RK3399_CRU_SOFTRST_CON(idx / 16), 1982 mask << 16 | (on ? mask : 0)); 1983 } 1984 1985 /* PMUCRU */ 1986 1987 struct rkclock rk3399_pmu_clocks[] = { 1988 { 1989 RK3399_CLK_I2C0, RK3399_PMUCRU_CLKSEL_CON(2), 1990 0, DIV(6, 0), 1991 { RK3399_PLL_PPLL } 1992 }, 1993 { 1994 RK3399_CLK_I2C4, RK3399_PMUCRU_CLKSEL_CON(3), 1995 0, DIV(6, 0), 1996 { RK3399_PLL_PPLL } 1997 }, 1998 { 1999 RK3399_CLK_I2C8, RK3399_PMUCRU_CLKSEL_CON(2), 2000 0, DIV(14, 8), 2001 { RK3399_PLL_PPLL } 2002 }, 2003 { 2004 /* Sentinel */ 2005 } 2006 }; 2007 2008 void 2009 rk3399_pmu_init(struct rkclock_softc *sc) 2010 { 2011 sc->sc_clocks = rk3399_pmu_clocks; 2012 rk3399_pmucru_sc = sc; 2013 } 2014 2015 uint32_t 2016 rk3399_pmu_get_frequency(void *cookie, uint32_t *cells) 2017 { 2018 struct rkclock_softc *sc = cookie; 2019 uint32_t idx = cells[0]; 2020 2021 switch (idx) { 2022 case RK3399_PLL_PPLL: 2023 return rk3399_get_pll(sc, RK3399_PMUCRU_PPLL_CON(0)); 2024 default: 2025 break; 2026 } 2027 2028 return rkclock_get_frequency(sc, idx); 2029 } 2030 2031 int 2032 rk3399_pmu_set_frequency(void *cookie, uint32_t *cells, uint32_t freq) 2033 { 2034 struct rkclock_softc *sc = cookie; 2035 uint32_t idx = cells[0]; 2036 2037 switch (idx) { 2038 case RK3399_PLL_PPLL: 2039 return rk3399_set_pll(sc, RK3399_PMUCRU_PPLL_CON(0), freq); 2040 break; 2041 default: 2042 break; 2043 } 2044 2045 return rkclock_set_frequency(sc, idx, freq); 2046 } 2047 2048 void 2049 rk3399_pmu_enable(void *cookie, uint32_t *cells, int on) 2050 { 2051 uint32_t idx = cells[0]; 2052 2053 switch (idx) { 2054 case RK3399_CLK_I2C0: 2055 case RK3399_CLK_I2C4: 2056 case RK3399_CLK_I2C8: 2057 case RK3399_PCLK_I2C0: 2058 case RK3399_PCLK_I2C4: 2059 case RK3399_PCLK_I2C8: 2060 /* Enabled by default. */ 2061 break; 2062 default: 2063 printf("%s: 0x%08x\n", __func__, idx); 2064 break; 2065 } 2066 } 2067 2068 void 2069 rk3399_pmu_reset(void *cookie, uint32_t *cells, int on) 2070 { 2071 uint32_t idx = cells[0]; 2072 2073 printf("%s: 0x%08x\n", __func__, idx); 2074 } 2075