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