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