1 /* $OpenBSD: rkclock.c,v 1.76 2023/04/27 08:55:59 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 #define RK3568_PMUCRU_GATE_CON(i) (0x0180 + (i) * 4) 190 191 /* RK3588 registers */ 192 #define RK3588_CRU_AUPLL_CON(i) (0x00180 + (i) * 4) 193 #define RK3588_CRU_CPLL_CON(i) (0x001a0 + (i) * 4) 194 #define RK3588_CRU_GPLL_CON(i) (0x001c0 + (i) * 4) 195 #define RK3588_CRU_NPLL_CON(i) (0x001e0 + (i) * 4) 196 #define RK3588_CRU_PLL_M_MASK (0x3ff << 0) 197 #define RK3588_CRU_PLL_M_SHIFT 0 198 #define RK3588_CRU_PLL_RESETB (1 << 13) 199 #define RK3588_CRU_PLL_S_MASK (0x7 << 6) 200 #define RK3588_CRU_PLL_S_SHIFT 6 201 #define RK3588_CRU_PLL_P_MASK (0x3f << 0) 202 #define RK3588_CRU_PLL_P_SHIFT 0 203 #define RK3588_CRU_PLL_K_MASK (0xffff << 0) 204 #define RK3588_CRU_PLL_K_SHIFT 0 205 #define RK3588_CRU_PLL_PLL_LOCK (1 << 15) 206 #define RK3588_CRU_MODE_CON 0x00280 207 #define RK3588_CRU_MODE_MASK 0x3 208 #define RK3588_CRU_MODE_SLOW 0x0 209 #define RK3588_CRU_MODE_NORMAL 0x1 210 211 #define RK3588_CRU_CLKSEL_CON(i) (0x00300 + (i) * 4) 212 #define RK3588_CRU_GATE_CON(i) (0x00800 + (i) * 4) 213 #define RK3588_CRU_SOFTRST_CON(i) (0x00a00 + (i) * 4) 214 215 #define RK3588_PHPTOPCRU_PPLL_CON(i) (0x08200 + (i) * 4) 216 #define RK3588_PHPTOPCRU_SOFTRST_CON(i) (0x08a00 + (i) * 4) 217 #define RK3588_PMUCRU_CLKSEL_CON(i) (0x30300 + (i) * 4) 218 219 #include "rkclock_clocks.h" 220 221 struct rkclock { 222 uint16_t idx; 223 uint32_t reg; 224 uint16_t sel_mask; 225 uint16_t div_mask; 226 uint16_t parents[8]; 227 uint32_t flags; 228 }; 229 230 #define SEL(l, f) (((1 << (l - f + 1)) - 1) << f) 231 #define DIV(l, f) SEL(l, f) 232 233 #define FIXED_PARENT (1 << 0) 234 #define SET_PARENT (1 << 1) 235 236 #define HREAD4(sc, reg) \ 237 (bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg))) 238 #define HWRITE4(sc, reg, val) \ 239 bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val)) 240 #define HSET4(sc, reg, bits) \ 241 HWRITE4((sc), (reg), HREAD4((sc), (reg)) | (bits)) 242 #define HCLR4(sc, reg, bits) \ 243 HWRITE4((sc), (reg), HREAD4((sc), (reg)) & ~(bits)) 244 245 struct rkclock_softc { 246 struct device sc_dev; 247 bus_space_tag_t sc_iot; 248 bus_space_handle_t sc_ioh; 249 struct regmap *sc_grf; 250 251 uint32_t sc_phandle; 252 const struct rkclock *sc_clocks; 253 254 struct clock_device sc_cd; 255 struct reset_device sc_rd; 256 }; 257 258 int rkclock_match(struct device *, void *, void *); 259 void rkclock_attach(struct device *, struct device *, void *); 260 261 const struct cfattach rkclock_ca = { 262 sizeof (struct rkclock_softc), rkclock_match, rkclock_attach 263 }; 264 265 struct cfdriver rkclock_cd = { 266 NULL, "rkclock", DV_DULL 267 }; 268 269 void rk3288_init(struct rkclock_softc *); 270 uint32_t rk3288_get_frequency(void *, uint32_t *); 271 int rk3288_set_frequency(void *, uint32_t *, uint32_t); 272 void rk3288_enable(void *, uint32_t *, int); 273 void rk3288_reset(void *, uint32_t *, int); 274 275 void rk3308_init(struct rkclock_softc *); 276 uint32_t rk3308_get_frequency(void *, uint32_t *); 277 int rk3308_set_frequency(void *, uint32_t *, uint32_t); 278 int rk3308_set_parent(void *, uint32_t *, uint32_t *); 279 void rk3308_enable(void *, uint32_t *, int); 280 void rk3308_reset(void *, uint32_t *, int); 281 282 void rk3328_init(struct rkclock_softc *); 283 uint32_t rk3328_get_frequency(void *, uint32_t *); 284 int rk3328_set_frequency(void *, uint32_t *, uint32_t); 285 int rk3328_set_parent(void *, uint32_t *, uint32_t *); 286 void rk3328_enable(void *, uint32_t *, int); 287 void rk3328_reset(void *, uint32_t *, int); 288 289 void rk3399_init(struct rkclock_softc *); 290 uint32_t rk3399_get_frequency(void *, uint32_t *); 291 int rk3399_set_frequency(void *, uint32_t *, uint32_t); 292 int rk3399_set_parent(void *, uint32_t *, uint32_t *); 293 void rk3399_enable(void *, uint32_t *, int); 294 void rk3399_reset(void *, uint32_t *, int); 295 296 void rk3399_pmu_init(struct rkclock_softc *); 297 uint32_t rk3399_pmu_get_frequency(void *, uint32_t *); 298 int rk3399_pmu_set_frequency(void *, uint32_t *, uint32_t); 299 void rk3399_pmu_enable(void *, uint32_t *, int); 300 void rk3399_pmu_reset(void *, uint32_t *, int); 301 302 void rk3568_init(struct rkclock_softc *); 303 uint32_t rk3568_get_frequency(void *, uint32_t *); 304 int rk3568_set_frequency(void *, uint32_t *, uint32_t); 305 int rk3568_set_parent(void *, uint32_t *, uint32_t *); 306 void rk3568_enable(void *, uint32_t *, int); 307 void rk3568_reset(void *, uint32_t *, int); 308 309 void rk3568_pmu_init(struct rkclock_softc *); 310 uint32_t rk3568_pmu_get_frequency(void *, uint32_t *); 311 int rk3568_pmu_set_frequency(void *, uint32_t *, uint32_t); 312 void rk3568_pmu_enable(void *, uint32_t *, int); 313 void rk3568_pmu_reset(void *, uint32_t *, int); 314 315 void rk3588_init(struct rkclock_softc *); 316 uint32_t rk3588_get_frequency(void *, uint32_t *); 317 int rk3588_set_frequency(void *, uint32_t *, uint32_t); 318 void rk3588_enable(void *, uint32_t *, int); 319 void rk3588_reset(void *, uint32_t *, int); 320 321 struct rkclock_compat { 322 const char *compat; 323 const char *name; 324 int assign; 325 void (*init)(struct rkclock_softc *); 326 void (*enable)(void *, uint32_t *, int); 327 uint32_t (*get_frequency)(void *, uint32_t *); 328 int (*set_frequency)(void *, uint32_t *, uint32_t); 329 int (*set_parent)(void *, uint32_t *, uint32_t *); 330 void (*reset)(void *, uint32_t *, int); 331 }; 332 333 const struct rkclock_compat rkclock_compat[] = { 334 { 335 "rockchip,rk3288-cru", NULL, 0, rk3288_init, 336 rk3288_enable, rk3288_get_frequency, 337 rk3288_set_frequency, NULL, 338 rk3288_reset 339 }, 340 { 341 "rockchip,rk3308-cru", NULL, 1, rk3308_init, 342 rk3308_enable, rk3308_get_frequency, 343 rk3308_set_frequency, rk3308_set_parent, 344 rk3308_reset 345 }, 346 { 347 "rockchip,rk3328-cru", NULL, 1, rk3328_init, 348 rk3328_enable, rk3328_get_frequency, 349 rk3328_set_frequency, rk3328_set_parent, 350 rk3328_reset 351 }, 352 { 353 "rockchip,rk3399-cru", NULL, 1, rk3399_init, 354 rk3399_enable, rk3399_get_frequency, 355 rk3399_set_frequency, rk3399_set_parent, 356 rk3399_reset 357 }, 358 { 359 "rockchip,rk3399-pmucru", NULL, 1, rk3399_pmu_init, 360 rk3399_pmu_enable, rk3399_pmu_get_frequency, 361 rk3399_pmu_set_frequency, NULL, 362 rk3399_pmu_reset 363 }, 364 { 365 "rockchip,rk3568-cru", "CRU", 1, rk3568_init, 366 rk3568_enable, rk3568_get_frequency, 367 rk3568_set_frequency, rk3568_set_parent, 368 rk3568_reset 369 }, 370 { 371 "rockchip,rk3568-pmucru", "PMUCRU", 1, rk3568_pmu_init, 372 rk3568_pmu_enable, rk3568_pmu_get_frequency, 373 rk3568_pmu_set_frequency, NULL, 374 rk3568_pmu_reset 375 }, 376 { 377 "rockchip,rk3588-cru", NULL, 1, rk3588_init, 378 rk3588_enable, rk3588_get_frequency, 379 rk3588_set_frequency, NULL, 380 rk3588_reset 381 }, 382 }; 383 384 int 385 rkclock_match(struct device *parent, void *match, void *aux) 386 { 387 struct fdt_attach_args *faa = aux; 388 int i; 389 390 for (i = 0; i < nitems(rkclock_compat); i++) { 391 if (OF_is_compatible(faa->fa_node, rkclock_compat[i].compat)) 392 return 10; 393 } 394 395 return 0; 396 } 397 398 void 399 rkclock_attach(struct device *parent, struct device *self, void *aux) 400 { 401 struct rkclock_softc *sc = (struct rkclock_softc *)self; 402 struct fdt_attach_args *faa = aux; 403 uint32_t grf; 404 int i; 405 406 if (faa->fa_nreg < 1) { 407 printf(": no registers\n"); 408 return; 409 } 410 411 sc->sc_iot = faa->fa_iot; 412 if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr, 413 faa->fa_reg[0].size, 0, &sc->sc_ioh)) { 414 printf(": can't map registers\n"); 415 return; 416 } 417 418 grf = OF_getpropint(faa->fa_node, "rockchip,grf", 0); 419 sc->sc_grf = regmap_byphandle(grf); 420 421 sc->sc_phandle = OF_getpropint(faa->fa_node, "phandle", 0); 422 423 for (i = 0; i < nitems(rkclock_compat); i++) { 424 if (OF_is_compatible(faa->fa_node, rkclock_compat[i].compat)) { 425 break; 426 } 427 } 428 KASSERT(i < nitems(rkclock_compat)); 429 430 if (rkclock_compat[i].name != NULL) 431 printf(": %s", rkclock_compat[i].name); 432 433 printf("\n"); 434 435 if (rkclock_compat[i].init) 436 rkclock_compat[i].init(sc); 437 438 sc->sc_cd.cd_node = faa->fa_node; 439 sc->sc_cd.cd_cookie = sc; 440 sc->sc_cd.cd_enable = rkclock_compat[i].enable; 441 sc->sc_cd.cd_get_frequency = rkclock_compat[i].get_frequency; 442 sc->sc_cd.cd_set_frequency = rkclock_compat[i].set_frequency; 443 sc->sc_cd.cd_set_parent = rkclock_compat[i].set_parent; 444 clock_register(&sc->sc_cd); 445 446 sc->sc_rd.rd_node = faa->fa_node; 447 sc->sc_rd.rd_cookie = sc; 448 sc->sc_rd.rd_reset = rkclock_compat[i].reset; 449 reset_register(&sc->sc_rd); 450 451 if (rkclock_compat[i].assign) 452 clock_set_assigned(faa->fa_node); 453 } 454 455 const struct rkclock * 456 rkclock_lookup(struct rkclock_softc *sc, uint32_t idx) 457 { 458 const struct rkclock *clk; 459 460 for (clk = sc->sc_clocks; clk->idx; clk++) { 461 if (clk->idx == idx) 462 return clk; 463 } 464 465 return NULL; 466 } 467 468 uint32_t 469 rkclock_external_frequency(const char *name) 470 { 471 char buf[64] = {}; 472 int len, node; 473 474 /* 475 * Hunt through the device tree to find a fixed-rate clock 476 * that has the requested clock output signal name. This may 477 * be too simple. 478 */ 479 node = OF_peer(0); 480 for (node = OF_child(node); node != 0; node = OF_peer(node)) { 481 len = OF_getproplen(node, "clock-output-names"); 482 if (len <= 0 || len > sizeof(buf)) 483 continue; 484 OF_getprop(node, "clock-output-names", buf, sizeof(buf)); 485 if (strcmp(buf, name) != 0) 486 continue; 487 if (OF_is_compatible(node, "fixed-clock")) 488 return OF_getpropint(node, "clock-frequency", 0); 489 } 490 491 return 0; 492 } 493 494 uint32_t 495 rkclock_div_con(struct rkclock_softc *sc, const struct rkclock *clk, 496 uint32_t mux, uint32_t freq) 497 { 498 uint32_t parent_freq, div, div_con, max_div_con; 499 uint32_t idx = clk->parents[mux]; 500 501 /* Derive maximum value from mask. */ 502 max_div_con = clk->div_mask >> (ffs(clk->div_mask) - 1); 503 504 parent_freq = sc->sc_cd.cd_get_frequency(sc, &idx); 505 div = (parent_freq + freq - 1) / freq; 506 div_con = (div > 0 ? div - 1 : 0); 507 return (div_con < max_div_con) ? div_con : max_div_con; 508 } 509 510 uint32_t 511 rkclock_freq(struct rkclock_softc *sc, const struct rkclock *clk, 512 uint32_t mux, uint32_t freq) 513 { 514 uint32_t parent_freq, div_con; 515 uint32_t idx = clk->parents[mux]; 516 517 parent_freq = sc->sc_cd.cd_get_frequency(sc, &idx); 518 div_con = rkclock_div_con(sc, clk, mux, freq); 519 return parent_freq / (div_con + 1); 520 } 521 522 uint32_t 523 rkclock_get_frequency(struct rkclock_softc *sc, uint32_t idx) 524 { 525 const struct rkclock *clk; 526 uint32_t reg, mux, div_con; 527 int shift; 528 529 clk = rkclock_lookup(sc, idx); 530 if (clk == NULL) { 531 printf("%s(%s, %u)\n", __func__, sc->sc_dev.dv_xname, idx); 532 return 0; 533 } 534 535 reg = HREAD4(sc, clk->reg); 536 shift = ffs(clk->sel_mask) - 1; 537 if (shift == -1) 538 mux = 0; 539 else 540 mux = (reg & clk->sel_mask) >> shift; 541 shift = ffs(clk->div_mask) - 1; 542 if (shift == -1) 543 div_con = 0; 544 else 545 div_con = (reg & clk->div_mask) >> shift; 546 547 if (clk->parents[mux] == 0) { 548 printf("%s: parent 0x%08x\n", __func__, idx); 549 return 0; 550 } 551 idx = clk->parents[mux]; 552 return sc->sc_cd.cd_get_frequency(sc, &idx) / (div_con + 1); 553 } 554 555 int 556 rkclock_set_frequency(struct rkclock_softc *sc, uint32_t idx, uint32_t freq) 557 { 558 const struct rkclock *clk; 559 uint32_t reg, mux, div_con; 560 uint32_t best_freq, best_mux, f; 561 uint32_t parent; 562 int sel_shift, div_shift, i; 563 564 clk = rkclock_lookup(sc, idx); 565 if (clk == NULL) { 566 printf("%s(%s, %u, %u)\n", __func__, sc->sc_dev.dv_xname, 567 idx, freq); 568 return -1; 569 } 570 571 reg = HREAD4(sc, clk->reg); 572 sel_shift = ffs(clk->sel_mask) - 1; 573 if (sel_shift == -1) 574 mux = sel_shift = 0; 575 else 576 mux = (reg & clk->sel_mask) >> sel_shift; 577 578 if (clk->parents[mux] == 0) { 579 printf("%s(%s, %u, %u) parent\n", __func__, 580 sc->sc_dev.dv_xname, idx, freq); 581 return 0; 582 } 583 584 if (clk->flags & SET_PARENT) { 585 parent = clk->parents[mux]; 586 sc->sc_cd.cd_set_frequency(sc, &parent, freq); 587 if (clk->div_mask == 0) 588 return 0; 589 } 590 591 /* 592 * If there is no divider, pick the parent with the frequency 593 * closest to the target frequency. 594 */ 595 if (clk->div_mask == 0) { 596 /* 597 * Start out with the current parent. This prevents 598 * unnecessary switching to a different parent. 599 */ 600 parent = clk->parents[mux]; 601 best_freq = sc->sc_cd.cd_get_frequency(sc, &parent); 602 best_mux = mux; 603 604 for (i = 0; i < nitems(clk->parents); i++) { 605 if (clk->parents[i] == 0) 606 continue; 607 parent = clk->parents[i]; 608 f = sc->sc_cd.cd_get_frequency(sc, &parent); 609 if ((best_freq > freq && f < best_freq) || 610 (f > best_freq && f <= freq)) { 611 best_freq = f; 612 best_mux = i; 613 } 614 } 615 616 HWRITE4(sc, clk->reg, 617 clk->sel_mask << 16 | best_mux << sel_shift); 618 return 0; 619 } 620 621 /* 622 * Start out with the current parent. This prevents 623 * unnecessary switching to a different parent. 624 */ 625 best_freq = rkclock_freq(sc, clk, mux, freq); 626 best_mux = mux; 627 628 /* 629 * Find the parent that allows configuration of a frequency 630 * closest to the target frequency. 631 */ 632 if ((clk->flags & FIXED_PARENT) == 0) { 633 for (i = 0; i < nitems(clk->parents); i++) { 634 if (clk->parents[i] == 0) 635 continue; 636 f = rkclock_freq(sc, clk, i, freq); 637 if ((best_freq > freq && f < best_freq) || 638 (f > best_freq && f <= freq)) { 639 best_freq = f; 640 best_mux = i; 641 } 642 } 643 } 644 645 div_con = rkclock_div_con(sc, clk, best_mux, freq); 646 div_shift = ffs(clk->div_mask) - 1; 647 HWRITE4(sc, clk->reg, 648 clk->sel_mask << 16 | best_mux << sel_shift | 649 clk->div_mask << 16 | div_con << div_shift); 650 return 0; 651 } 652 653 int 654 rkclock_set_parent(struct rkclock_softc *sc, uint32_t idx, uint32_t parent) 655 { 656 const struct rkclock *clk; 657 uint32_t mux; 658 int shift; 659 660 clk = rkclock_lookup(sc, idx); 661 if (clk == NULL || clk->sel_mask == 0) { 662 printf("%s: 0x%08x\n", __func__, idx); 663 return -1; 664 } 665 666 for (mux = 0; mux < nitems(clk->parents); mux++) { 667 if (clk->parents[mux] == parent) 668 break; 669 } 670 if (mux == nitems(clk->parents) || parent == 0) { 671 printf("%s: 0x%08x parent 0x%08x\n", __func__, idx, parent); 672 return -1; 673 } 674 675 shift = ffs(clk->sel_mask) - 1; 676 HWRITE4(sc, clk->reg, clk->sel_mask << 16 | mux << shift); 677 return 0; 678 } 679 680 /* 681 * Rockchip RK3288 682 */ 683 684 const struct rkclock rk3288_clocks[] = { 685 { 686 RK3288_CLK_SDMMC, RK3288_CRU_CLKSEL_CON(11), 687 SEL(7, 6), DIV(5, 0), 688 { RK3288_PLL_CPLL, RK3288_PLL_GPLL, RK3288_XIN24M } 689 } 690 }; 691 692 void 693 rk3288_init(struct rkclock_softc *sc) 694 { 695 int node; 696 697 /* 698 * Since the hardware comes up with a really conservative CPU 699 * clock frequency, and U-Boot doesn't set it to a more 700 * reasonable default, try to do so here. These defaults were 701 * chosen assuming that the CPU voltage is at least 1.1 V. 702 * Only do this on the Tinker-RK3288 for now where this is 703 * likely to be true given the default voltages for the 704 * regulators on that board. 705 */ 706 node = OF_finddevice("/"); 707 if (OF_is_compatible(node, "rockchip,rk3288-tinker")) { 708 uint32_t idx; 709 710 /* Run at 1.2 GHz. */ 711 idx = RK3288_ARMCLK; 712 rk3288_set_frequency(sc, &idx, 1200000000); 713 } 714 715 sc->sc_clocks = rk3288_clocks; 716 } 717 718 uint32_t 719 rk3288_get_pll(struct rkclock_softc *sc, bus_size_t base) 720 { 721 uint32_t clkod, clkr, clkf; 722 uint32_t reg; 723 724 reg = HREAD4(sc, base); 725 clkod = (reg & RK3288_CRU_PLL_CLKOD_MASK) >> 726 RK3288_CRU_PLL_CLKOD_SHIFT; 727 clkr = (reg & RK3288_CRU_PLL_CLKR_MASK) >> 728 RK3288_CRU_PLL_CLKR_SHIFT; 729 reg = HREAD4(sc, base + 4); 730 clkf = (reg & RK3288_CRU_PLL_CLKF_MASK) >> 731 RK3288_CRU_PLL_CLKF_SHIFT; 732 return 24000000ULL * (clkf + 1) / (clkr + 1) / (clkod + 1); 733 } 734 735 int 736 rk3288_set_pll(struct rkclock_softc *sc, bus_size_t base, uint32_t freq) 737 { 738 int shift = 4 * (base / RK3288_CRU_CPLL_CON(0)); 739 uint32_t no, nr, nf; 740 741 /* 742 * It is not clear whether all combinations of the clock 743 * dividers result in a stable clock. Therefore this function 744 * only supports a limited set of PLL clock rates. For now 745 * this set covers all the CPU frequencies supported by the 746 * Linux kernel. 747 */ 748 switch (freq) { 749 case 1800000000: 750 case 1704000000: 751 case 1608000000: 752 case 1512000000: 753 case 1488000000: 754 case 1416000000: 755 case 1200000000: 756 nr = no = 1; 757 break; 758 case 1008000000: 759 case 816000000: 760 case 696000000: 761 case 600000000: 762 nr = 1; no = 2; 763 break; 764 case 408000000: 765 case 312000000: 766 nr = 1; no = 4; 767 break; 768 case 216000000: 769 case 126000000: 770 nr = 1; no = 8; 771 break; 772 default: 773 printf("%s: %u Hz\n", __func__, freq); 774 return -1; 775 } 776 777 /* Calculate feedback divider. */ 778 nf = freq * nr * no / 24000000; 779 780 /* 781 * Select slow mode to guarantee a stable clock while we're 782 * adjusting the PLL. 783 */ 784 HWRITE4(sc, RK3288_CRU_MODE_CON, 785 (RK3288_CRU_MODE_PLL_WORK_MODE_MASK << 16 | 786 RK3288_CRU_MODE_PLL_WORK_MODE_SLOW) << shift); 787 788 /* Assert reset. */ 789 HWRITE4(sc, base + 0x000c, 790 RK3288_CRU_PLL_RESET << 16 | RK3288_CRU_PLL_RESET); 791 792 /* Set PLL rate. */ 793 HWRITE4(sc, base + 0x0000, 794 RK3288_CRU_PLL_CLKR_MASK << 16 | 795 (nr - 1) << RK3288_CRU_PLL_CLKR_SHIFT | 796 RK3288_CRU_PLL_CLKOD_MASK << 16 | 797 (no - 1) << RK3288_CRU_PLL_CLKOD_SHIFT); 798 HWRITE4(sc, base + 0x0004, 799 RK3288_CRU_PLL_CLKF_MASK << 16 | 800 (nf - 1) << RK3288_CRU_PLL_CLKF_SHIFT); 801 802 /* Deassert reset and wait. */ 803 HWRITE4(sc, base + 0x000c, 804 RK3288_CRU_PLL_RESET << 16); 805 delay((nr * 500 / 24) + 1); 806 807 /* Switch back to normal mode. */ 808 HWRITE4(sc, RK3288_CRU_MODE_CON, 809 (RK3288_CRU_MODE_PLL_WORK_MODE_MASK << 16 | 810 RK3288_CRU_MODE_PLL_WORK_MODE_NORMAL) << shift); 811 812 return 0; 813 } 814 815 uint32_t 816 rk3288_get_frequency(void *cookie, uint32_t *cells) 817 { 818 struct rkclock_softc *sc = cookie; 819 uint32_t idx = cells[0]; 820 uint32_t reg, mux, div_con, aclk_div_con; 821 822 switch (idx) { 823 case RK3288_PLL_APLL: 824 return rk3288_get_pll(sc, RK3288_CRU_APLL_CON(0)); 825 case RK3288_PLL_CPLL: 826 return rk3288_get_pll(sc, RK3288_CRU_CPLL_CON(0)); 827 case RK3288_PLL_GPLL: 828 return rk3288_get_pll(sc, RK3288_CRU_GPLL_CON(0)); 829 case RK3288_PLL_NPLL: 830 return rk3288_get_pll(sc, RK3288_CRU_NPLL_CON(0)); 831 case RK3288_ARMCLK: 832 reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(0)); 833 mux = (reg >> 15) & 0x1; 834 div_con = (reg >> 8) & 0x1f; 835 idx = (mux == 0) ? RK3288_PLL_APLL : RK3288_PLL_GPLL; 836 return rk3288_get_frequency(sc, &idx) / (div_con + 1); 837 case RK3288_XIN24M: 838 return 24000000; 839 case RK3288_CLK_UART0: 840 reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(13)); 841 mux = (reg >> 8) & 0x3; 842 div_con = reg & 0x7f; 843 if (mux == 2) 844 return 24000000 / (div_con + 1); 845 break; 846 case RK3288_CLK_UART1: 847 reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(14)); 848 mux = (reg >> 8) & 0x3; 849 div_con = reg & 0x7f; 850 if (mux == 2) 851 return 24000000 / (div_con + 1); 852 break; 853 case RK3288_CLK_UART2: 854 reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(15)); 855 mux = (reg >> 8) & 0x3; 856 div_con = reg & 0x7f; 857 if (mux == 2) 858 return 24000000 / (div_con + 1); 859 break; 860 case RK3288_CLK_UART3: 861 reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(16)); 862 mux = (reg >> 8) & 0x3; 863 div_con = reg & 0x7f; 864 if (mux == 2) 865 return 24000000 / (div_con + 1); 866 break; 867 case RK3288_CLK_UART4: 868 reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(3)); 869 mux = (reg >> 8) & 0x3; 870 div_con = reg & 0x7f; 871 if (mux == 2) 872 return 24000000 / (div_con + 1); 873 break; 874 case RK3288_CLK_MAC: 875 reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(21)); 876 if (reg & 0x10) 877 return 125000000; 878 mux = (reg >> 0) & 0x3; 879 div_con = (reg >> 8) & 0x1f; 880 switch (mux) { 881 case 0: 882 idx = RK3288_PLL_NPLL; 883 break; 884 case 1: 885 idx = RK3288_PLL_CPLL; 886 break; 887 case 2: 888 idx = RK3288_PLL_GPLL; 889 break; 890 default: 891 return 0; 892 } 893 return rk3288_get_frequency(sc, &idx) / (div_con + 1); 894 case RK3288_PCLK_I2C0: 895 case RK3288_PCLK_I2C2: 896 reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(1)); 897 mux = (reg >> 15) & 0x1; 898 /* pd_bus_pclk_div_con */ 899 div_con = (reg >> 12) & 0x7; 900 if (mux == 1) 901 idx = RK3288_PLL_GPLL; 902 else 903 idx = RK3288_PLL_CPLL; 904 return rk3288_get_frequency(sc, &idx) / (div_con + 1); 905 case RK3288_PCLK_I2C1: 906 case RK3288_PCLK_I2C3: 907 case RK3288_PCLK_I2C4: 908 case RK3288_PCLK_I2C5: 909 reg = HREAD4(sc, RK3288_CRU_CLKSEL_CON(10)); 910 mux = (reg >> 15) & 0x1; 911 /* peri_pclk_div_con */ 912 div_con = (reg >> 12) & 0x3; 913 /* peri_aclk_div_con */ 914 aclk_div_con = reg & 0xf; 915 if (mux == 1) 916 idx = RK3288_PLL_GPLL; 917 else 918 idx = RK3288_PLL_CPLL; 919 return (rk3288_get_frequency(sc, &idx) / (aclk_div_con + 1)) >> 920 div_con; 921 default: 922 break; 923 } 924 925 return rkclock_get_frequency(sc, idx); 926 } 927 928 int 929 rk3288_set_frequency(void *cookie, uint32_t *cells, uint32_t freq) 930 { 931 struct rkclock_softc *sc = cookie; 932 uint32_t idx = cells[0]; 933 int error; 934 935 switch (idx) { 936 case RK3288_PLL_APLL: 937 return rk3288_set_pll(sc, RK3288_CRU_APLL_CON(0), freq); 938 case RK3288_ARMCLK: 939 idx = RK3288_PLL_APLL; 940 error = rk3288_set_frequency(sc, &idx, freq); 941 if (error == 0) { 942 HWRITE4(sc, RK3288_CRU_CLKSEL_CON(0), 943 ((1 << 15) | (0x1f << 8)) << 16); 944 } 945 return error; 946 default: 947 break; 948 } 949 950 return rkclock_set_frequency(sc, idx, freq); 951 } 952 953 void 954 rk3288_enable(void *cookie, uint32_t *cells, int on) 955 { 956 uint32_t idx = cells[0]; 957 958 switch (idx) { 959 case RK3288_CLK_SDMMC: 960 case RK3288_CLK_TSADC: 961 case RK3288_CLK_UART0: 962 case RK3288_CLK_UART1: 963 case RK3288_CLK_UART2: 964 case RK3288_CLK_UART3: 965 case RK3288_CLK_UART4: 966 case RK3288_CLK_MAC_RX: 967 case RK3288_CLK_MAC_TX: 968 case RK3288_CLK_SDMMC_DRV: 969 case RK3288_CLK_SDMMC_SAMPLE: 970 case RK3288_CLK_MAC: 971 case RK3288_ACLK_GMAC: 972 case RK3288_PCLK_GMAC: 973 case RK3288_PCLK_I2C0: 974 case RK3288_PCLK_I2C1: 975 case RK3288_PCLK_I2C2: 976 case RK3288_PCLK_I2C3: 977 case RK3288_PCLK_I2C4: 978 case RK3288_PCLK_I2C5: 979 case RK3288_PCLK_TSADC: 980 case RK3288_HCLK_HOST0: 981 case RK3288_HCLK_SDMMC: 982 /* Enabled by default. */ 983 break; 984 default: 985 printf("%s: 0x%08x\n", __func__, idx); 986 break; 987 } 988 } 989 990 void 991 rk3288_reset(void *cookie, uint32_t *cells, int on) 992 { 993 struct rkclock_softc *sc = cookie; 994 uint32_t idx = cells[0]; 995 uint32_t mask = (1 << (idx % 16)); 996 997 HWRITE4(sc, RK3288_CRU_SOFTRST_CON(idx / 16), 998 mask << 16 | (on ? mask : 0)); 999 } 1000 1001 /* 1002 * Rockchip RK3308 1003 */ 1004 1005 const struct rkclock rk3308_clocks[] = { 1006 { 1007 RK3308_CLK_RTC32K, RK3308_CRU_CLKSEL_CON(2), 1008 SEL(10, 9), 0, 1009 { RK3308_PLL_VPLL0, RK3308_PLL_VPLL1 } 1010 }, 1011 { 1012 RK3308_CLK_UART0, RK3308_CRU_CLKSEL_CON(10), 1013 SEL(15, 13), DIV(4, 0), 1014 { RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1, 1015 RK3308_USB480M, RK3308_XIN24M } 1016 }, 1017 { 1018 RK3308_CLK_UART1, RK3308_CRU_CLKSEL_CON(13), 1019 SEL(15, 13), DIV(4, 0), 1020 { RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1, 1021 RK3308_USB480M, RK3308_XIN24M } 1022 }, 1023 { 1024 RK3308_CLK_UART2, RK3308_CRU_CLKSEL_CON(16), 1025 SEL(15, 13), DIV(4, 0), 1026 { RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1, 1027 RK3308_USB480M, RK3308_XIN24M } 1028 }, 1029 { 1030 RK3308_CLK_UART3, RK3308_CRU_CLKSEL_CON(19), 1031 SEL(15, 13), DIV(4, 0), 1032 { RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1, 1033 RK3308_USB480M, RK3308_XIN24M } 1034 }, 1035 { 1036 RK3308_CLK_UART4, RK3308_CRU_CLKSEL_CON(22), 1037 SEL(15, 13), DIV(4, 0), 1038 { RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1, 1039 RK3308_USB480M, RK3308_XIN24M } 1040 }, 1041 { 1042 RK3308_CLK_PWM0, RK3308_CRU_CLKSEL_CON(29), 1043 SEL(15, 14), DIV(6, 0), 1044 { RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_XIN24M } 1045 }, 1046 { 1047 RK3308_CLK_TSADC, RK3308_CRU_CLKSEL_CON(33), 1048 0, DIV(10, 0), 1049 { RK3308_XIN24M } 1050 }, 1051 { 1052 RK3308_CLK_SARADC, RK3308_CRU_CLKSEL_CON(34), 1053 0, DIV(10, 0), 1054 { RK3308_XIN24M } 1055 }, 1056 { 1057 RK3308_CLK_CRYPTO, RK3308_CRU_CLKSEL_CON(7), 1058 SEL(7, 6), DIV(4, 0), 1059 { RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1, 0 } 1060 }, 1061 { 1062 RK3308_CLK_CRYPTO_APK, RK3308_CRU_CLKSEL_CON(7), 1063 SEL(15, 14), DIV(12, 8), 1064 { RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1, 0 } 1065 }, 1066 { 1067 RK3308_CLK_SDMMC, RK3308_CRU_CLKSEL_CON(39), 1068 SEL(9, 8), DIV(7, 0), 1069 { RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1, 1070 RK3308_XIN24M } 1071 }, 1072 { 1073 RK3308_CLK_SDIO, RK3308_CRU_CLKSEL_CON(40), 1074 SEL(9, 8), DIV(7, 0), 1075 { RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1, 1076 RK3308_XIN24M } 1077 }, 1078 { 1079 RK3308_CLK_EMMC, RK3308_CRU_CLKSEL_CON(41), 1080 SEL(9, 8), DIV(7, 0), 1081 { RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1, 1082 RK3308_XIN24M } 1083 }, 1084 { 1085 RK3308_CLK_MAC_SRC, RK3308_CRU_CLKSEL_CON(43), 1086 SEL(7, 6), DIV(4, 0), 1087 { RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1, 0 } 1088 }, 1089 { 1090 RK3308_CLK_MAC, RK3308_CRU_CLKSEL_CON(43), 1091 SEL(14, 13), 0, 1092 { RK3308_CLK_MAC_SRC, 0 }, 1093 SET_PARENT 1094 }, 1095 { 1096 RK3308_ACLK_PERI_SRC, RK3308_CRU_CLKSEL_CON(36), 1097 SEL(7, 6), 0, 1098 { RK3308_PLL_DPLL, RK3308_PLL_VPLL0, RK3308_PLL_VPLL1, 0 } 1099 }, 1100 { 1101 RK3308_PCLK_PERI, RK3308_CRU_CLKSEL_CON(37), 1102 0, DIV(12, 8), 1103 { RK3308_ACLK_PERI_SRC } 1104 }, 1105 { 1106 RK3308_PCLK_MAC, 0, 0, 0, 1107 { RK3308_PCLK_PERI } 1108 }, 1109 1110 { 1111 /* Sentinel */ 1112 } 1113 }; 1114 1115 void 1116 rk3308_init(struct rkclock_softc *sc) 1117 { 1118 int i; 1119 1120 /* The code below assumes all clocks are enabled. Check this!. */ 1121 for (i = 0; i <= 14; i++) { 1122 if (HREAD4(sc, RK3308_CRU_CLKGATE_CON(i)) != 0x00000000) { 1123 printf("CRU_CLKGATE_CON%d: 0x%08x\n", i, 1124 HREAD4(sc, RK3308_CRU_CLKGATE_CON(i))); 1125 } 1126 } 1127 sc->sc_clocks = rk3308_clocks; 1128 } 1129 1130 uint32_t 1131 rk3308_armclk_parent(uint32_t mux) 1132 { 1133 switch (mux) { 1134 case 0: 1135 return RK3308_PLL_APLL; 1136 case 1: 1137 return RK3308_PLL_VPLL0; 1138 case 2: 1139 return RK3308_PLL_VPLL1; 1140 } 1141 1142 return 0; 1143 } 1144 1145 uint32_t 1146 rk3308_get_armclk(struct rkclock_softc *sc) 1147 { 1148 uint32_t reg, mux, div_con; 1149 uint32_t idx; 1150 1151 reg = HREAD4(sc, RK3308_CRU_CLKSEL_CON(0)); 1152 mux = (reg & RK3308_CRU_CORE_CLK_PLL_SEL_MASK) >> 1153 RK3308_CRU_CORE_CLK_PLL_SEL_SHIFT; 1154 div_con = (reg & RK3308_CRU_CLK_CORE_DIV_CON_MASK) >> 1155 RK3308_CRU_CLK_CORE_DIV_CON_SHIFT; 1156 idx = rk3308_armclk_parent(mux); 1157 1158 return rk3308_get_frequency(sc, &idx) / (div_con + 1); 1159 } 1160 1161 int 1162 rk3308_set_armclk(struct rkclock_softc *sc, uint32_t freq) 1163 { 1164 uint32_t reg, mux; 1165 uint32_t old_freq, div; 1166 uint32_t idx; 1167 1168 old_freq = rk3308_get_armclk(sc); 1169 if (freq == old_freq) 1170 return 0; 1171 1172 reg = HREAD4(sc, RK3308_CRU_CLKSEL_CON(0)); 1173 mux = (reg & RK3308_CRU_CORE_CLK_PLL_SEL_MASK) >> 1174 RK3308_CRU_CORE_CLK_PLL_SEL_SHIFT; 1175 1176 /* Keep the pclk_dbg clock at or below 300 MHz. */ 1177 div = 1; 1178 while (freq / (div + 1) > 300000000) 1179 div++; 1180 /* and make sure we use an odd divider. */ 1181 if ((div % 2) == 0) 1182 div++; 1183 1184 /* When ramping up, set clock dividers first. */ 1185 if (freq > old_freq) { 1186 HWRITE4(sc, RK3308_CRU_CLKSEL_CON(0), 1187 RK3308_CRU_CLK_CORE_DIV_CON_MASK << 16 | 1188 0 << RK3308_CRU_CLK_CORE_DIV_CON_SHIFT | 1189 RK3308_CRU_ACLK_CORE_DIV_CON_MASK << 16 | 1190 1 << RK3308_CRU_ACLK_CORE_DIV_CON_SHIFT | 1191 RK3308_CRU_CLK_CORE_DBG_DIV_CON_MASK << 16 | 1192 div << RK3308_CRU_CLK_CORE_DBG_DIV_CON_SHIFT); 1193 } 1194 1195 /* We always use VPLL1 and force the switch below if needed. */ 1196 idx = RK3308_PLL_VPLL1; 1197 rk3308_set_frequency(sc, &idx, freq); 1198 1199 /* When ramping down, set clock dividers last. */ 1200 if (freq < old_freq || mux != 2) { 1201 HWRITE4(sc, RK3308_CRU_CLKSEL_CON(0), 1202 RK3308_CRU_CORE_CLK_PLL_SEL_MASK << 16 | 1203 2 << RK3308_CRU_CORE_CLK_PLL_SEL_SHIFT | 1204 RK3308_CRU_CLK_CORE_DIV_CON_MASK << 16 | 1205 0 << RK3308_CRU_CLK_CORE_DIV_CON_SHIFT | 1206 RK3308_CRU_ACLK_CORE_DIV_CON_MASK << 16 | 1207 1 << RK3308_CRU_ACLK_CORE_DIV_CON_SHIFT | 1208 RK3308_CRU_CLK_CORE_DBG_DIV_CON_MASK << 16 | 1209 div << RK3308_CRU_CLK_CORE_DBG_DIV_CON_SHIFT); 1210 } 1211 1212 return 0; 1213 } 1214 1215 uint32_t 1216 rk3308_get_pll(struct rkclock_softc *sc, bus_size_t base) 1217 { 1218 uint32_t fbdiv, postdiv1, postdiv2, refdiv; 1219 uint32_t dsmpd, fracdiv; 1220 uint64_t frac = 0; 1221 uint32_t reg; 1222 1223 reg = HREAD4(sc, base + 0x0000); 1224 postdiv1 = (reg & RK3308_CRU_PLL_POSTDIV1_MASK) >> 1225 RK3308_CRU_PLL_POSTDIV1_SHIFT; 1226 fbdiv = (reg & RK3308_CRU_PLL_FBDIV_MASK) >> 1227 RK3308_CRU_PLL_FBDIV_SHIFT; 1228 reg = HREAD4(sc, base + 0x0004); 1229 dsmpd = (reg & RK3308_CRU_PLL_DSMPD); 1230 postdiv2 = (reg & RK3308_CRU_PLL_POSTDIV2_MASK) >> 1231 RK3308_CRU_PLL_POSTDIV2_SHIFT; 1232 refdiv = (reg & RK3308_CRU_PLL_REFDIV_MASK) >> 1233 RK3308_CRU_PLL_REFDIV_SHIFT; 1234 reg = HREAD4(sc, base + 0x0008); 1235 fracdiv = (reg & RK3308_CRU_PLL_FRACDIV_MASK) >> 1236 RK3308_CRU_PLL_FRACDIV_SHIFT; 1237 1238 if (dsmpd == 0) 1239 frac = (24000000ULL * fracdiv / refdiv) >> 24; 1240 return ((24000000ULL * fbdiv / refdiv) + frac) / postdiv1 / postdiv2; 1241 } 1242 1243 int 1244 rk3308_set_pll(struct rkclock_softc *sc, bus_size_t base, uint32_t freq) 1245 { 1246 uint32_t fbdiv, postdiv1, postdiv2, refdiv; 1247 int mode_shift = -1; 1248 1249 switch (base) { 1250 case RK3308_CRU_APLL_CON(0): 1251 mode_shift = 0; 1252 break; 1253 case RK3308_CRU_DPLL_CON(0): 1254 mode_shift = 2; 1255 break; 1256 case RK3308_CRU_VPLL0_CON(0): 1257 mode_shift = 4; 1258 break; 1259 case RK3308_CRU_VPLL1_CON(0): 1260 mode_shift = 6; 1261 break; 1262 } 1263 KASSERT(mode_shift != -1); 1264 1265 /* 1266 * It is not clear whether all combinations of the clock 1267 * dividers result in a stable clock. Therefore this function 1268 * only supports a limited set of PLL clock rates. For now 1269 * this set covers all the CPU frequencies supported by the 1270 * Linux kernel. 1271 */ 1272 switch (freq) { 1273 case 1608000000U: 1274 case 1584000000U: 1275 case 1560000000U: 1276 case 1536000000U: 1277 case 1512000000U: 1278 case 1488000000U: 1279 case 1464000000U: 1280 case 1440000000U: 1281 case 1416000000U: 1282 case 1392000000U: 1283 case 1368000000U: 1284 case 1344000000U: 1285 case 1320000000U: 1286 case 1296000000U: 1287 case 1272000000U: 1288 case 1248000000U: 1289 case 1200000000U: 1290 case 1104000000U: 1291 postdiv1 = postdiv2 = refdiv = 1; 1292 break; 1293 case 1188000000U: 1294 refdiv = 2; postdiv1 = postdiv2 = 1; 1295 break; 1296 case 1100000000U: 1297 refdiv = 12; postdiv1 = postdiv2 = 1; 1298 break; 1299 case 1000000000U: 1300 refdiv = 6; postdiv1 = postdiv2 = 1; 1301 break; 1302 case 1008000000U: 1303 case 984000000U: 1304 case 960000000U: 1305 case 936000000U: 1306 case 912000000U: 1307 case 888000000U: 1308 case 864000000U: 1309 case 840000000U: 1310 case 816000000U: 1311 case 696000000U: 1312 case 624000000U: 1313 postdiv1 = 2; postdiv2 = refdiv = 1; 1314 break; 1315 case 900000000U: 1316 refdiv = 4; postdiv1 = 2; postdiv2 = 1; 1317 break; 1318 case 800000000U: 1319 case 700000000U: 1320 case 500000000U: 1321 refdiv = 6; postdiv1 = 2; postdiv2 = 1; 1322 break; 1323 case 600000000U: 1324 case 504000000U: 1325 postdiv1 = 3; postdiv2 = refdiv = 1; 1326 break; 1327 case 594000000U: 1328 refdiv = 2; postdiv1 = 2; postdiv2 = 1; 1329 break; 1330 case 408000000U: 1331 case 312000000U: 1332 postdiv1 = postdiv2 = 2; refdiv = 1; 1333 break; 1334 case 216000000U: 1335 postdiv1 = 4; postdiv2 = 2; refdiv = 1; 1336 break; 1337 case 96000000U: 1338 postdiv1 = postdiv2 = 4; refdiv = 1; 1339 break; 1340 default: 1341 printf("%s: %u Hz\n", __func__, freq); 1342 return -1; 1343 } 1344 1345 /* Calculate feedback divider. */ 1346 fbdiv = freq * postdiv1 * postdiv2 * refdiv / 24000000; 1347 1348 /* 1349 * Select slow mode to guarantee a stable clock while we're 1350 * adjusting the PLL. 1351 */ 1352 HWRITE4(sc, RK3308_CRU_CRU_MODE, 1353 (RK3308_CRU_CRU_MODE_MASK << 16 | 1354 RK3308_CRU_CRU_MODE_SLOW) << mode_shift); 1355 1356 /* Set PLL rate. */ 1357 HWRITE4(sc, base + 0x0000, 1358 RK3308_CRU_PLL_POSTDIV1_MASK << 16 | 1359 postdiv1 << RK3308_CRU_PLL_POSTDIV1_SHIFT | 1360 RK3308_CRU_PLL_FBDIV_MASK << 16 | 1361 fbdiv << RK3308_CRU_PLL_FBDIV_SHIFT); 1362 HWRITE4(sc, base + 0x0004, 1363 RK3308_CRU_PLL_DSMPD << 16 | RK3308_CRU_PLL_DSMPD | 1364 RK3308_CRU_PLL_POSTDIV2_MASK << 16 | 1365 postdiv2 << RK3308_CRU_PLL_POSTDIV2_SHIFT | 1366 RK3308_CRU_PLL_REFDIV_MASK << 16 | 1367 refdiv << RK3308_CRU_PLL_REFDIV_SHIFT); 1368 1369 /* Wait for PLL to stabilize. */ 1370 while ((HREAD4(sc, base + 0x0004) & RK3308_CRU_PLL_PLL_LOCK) == 0) 1371 delay(10); 1372 1373 /* Switch back to normal mode. */ 1374 HWRITE4(sc, RK3308_CRU_CRU_MODE, 1375 (RK3308_CRU_CRU_MODE_MASK << 16 | 1376 RK3308_CRU_CRU_MODE_NORMAL) << mode_shift); 1377 1378 return 0; 1379 } 1380 1381 uint32_t 1382 rk3308_get_rtc32k(struct rkclock_softc *sc) 1383 { 1384 uint32_t reg, mux, pll, div_con; 1385 1386 reg = HREAD4(sc, RK3308_CRU_CLKSEL_CON(2)); 1387 mux = (reg & 0x300) >> 8; 1388 if (mux != 3) { 1389 printf("%s: RTC32K not using clk_32k_div\n", __func__); 1390 return 0; 1391 } 1392 1393 if ((reg >> 10) & 1) 1394 pll = RK3308_PLL_VPLL1; 1395 else 1396 pll = RK3308_PLL_VPLL0; 1397 1398 div_con = HREAD4(sc, RK3308_CRU_CLKSEL_CON(4)) & 0xffff; 1399 return rk3308_get_frequency(sc, &pll) / (div_con + 1); 1400 } 1401 1402 int 1403 rk3308_set_rtc32k(struct rkclock_softc *sc, uint32_t freq) 1404 { 1405 const struct rkclock *clk; 1406 uint32_t vpll0_freq, vpll1_freq, mux, div_con; 1407 1408 clk = rkclock_lookup(sc, RK3308_CLK_RTC32K); 1409 vpll0_freq = rkclock_freq(sc, clk, 0, freq); 1410 vpll1_freq = rkclock_freq(sc, clk, 1, freq); 1411 mux = 0; 1412 freq = vpll0_freq; 1413 1414 if ((vpll1_freq > vpll0_freq && vpll1_freq <= freq) || 1415 (vpll1_freq < vpll0_freq && vpll1_freq >= freq)) { 1416 mux = 1; 1417 freq = vpll1_freq; 1418 } 1419 1420 div_con = rkclock_div_con(sc, clk, mux, freq); 1421 HWRITE4(sc, RK3308_CRU_CLKSEL_CON(2), 1 << 26 | (mux << 10)); 1422 HWRITE4(sc, RK3308_CRU_CLKSEL_CON(4), 0xffff0000 | div_con); 1423 return 0; 1424 } 1425 1426 uint32_t 1427 rk3308_get_frequency(void *cookie, uint32_t *cells) 1428 { 1429 struct rkclock_softc *sc = cookie; 1430 uint32_t idx = cells[0]; 1431 1432 switch (idx) { 1433 case RK3308_PLL_APLL: 1434 return rk3308_get_pll(sc, RK3308_CRU_APLL_CON(0)); 1435 case RK3308_PLL_DPLL: 1436 return rk3308_get_pll(sc, RK3308_CRU_DPLL_CON(0)); 1437 case RK3308_PLL_VPLL0: 1438 return rk3308_get_pll(sc, RK3308_CRU_VPLL0_CON(0)); 1439 case RK3308_PLL_VPLL1: 1440 return rk3308_get_pll(sc, RK3308_CRU_VPLL1_CON(0)); 1441 case RK3308_ARMCLK: 1442 return rk3308_get_armclk(sc); 1443 case RK3308_XIN24M: 1444 return 24000000; 1445 case RK3308_CLK_RTC32K: 1446 return rk3308_get_rtc32k(sc); 1447 1448 /* 1449 * XXX The USB480M clock is external. Returning zero here will cause 1450 * it to be ignored for reparenting purposes. 1451 */ 1452 case RK3308_USB480M: 1453 return 0; 1454 default: 1455 break; 1456 } 1457 1458 return rkclock_get_frequency(sc, idx); 1459 } 1460 1461 int 1462 rk3308_set_frequency(void *cookie, uint32_t *cells, uint32_t freq) 1463 { 1464 struct rkclock_softc *sc = cookie; 1465 uint32_t idx = cells[0]; 1466 1467 switch (idx) { 1468 case RK3308_PLL_APLL: 1469 return rk3308_set_pll(sc, RK3308_CRU_APLL_CON(0), freq); 1470 case RK3308_PLL_DPLL: 1471 return rk3308_set_pll(sc, RK3308_CRU_DPLL_CON(0), freq); 1472 case RK3308_PLL_VPLL0: 1473 return rk3308_set_pll(sc, RK3308_CRU_VPLL0_CON(0), freq); 1474 case RK3308_PLL_VPLL1: 1475 return rk3308_set_pll(sc, RK3308_CRU_VPLL1_CON(0), freq); 1476 case RK3308_ARMCLK: 1477 return rk3308_set_armclk(sc, freq); 1478 case RK3308_CLK_RTC32K: 1479 return rk3308_set_rtc32k(sc, freq); 1480 default: 1481 break; 1482 } 1483 1484 return rkclock_set_frequency(sc, idx, freq); 1485 } 1486 1487 1488 int 1489 rk3308_set_parent(void *cookie, uint32_t *cells, uint32_t *pcells) 1490 { 1491 struct rkclock_softc *sc = cookie; 1492 1493 if (pcells[0] != sc->sc_phandle) 1494 return -1; 1495 1496 return rkclock_set_parent(sc, cells[0], pcells[1]); 1497 } 1498 1499 void 1500 rk3308_enable(void *cookie, uint32_t *cells, int on) 1501 { 1502 uint32_t idx = cells[0]; 1503 1504 /* 1505 * All clocks are enabled by default, so there is nothing for 1506 * us to do until we start disabling clocks. 1507 */ 1508 if (!on) 1509 printf("%s: 0x%08x\n", __func__, idx); 1510 } 1511 1512 void 1513 rk3308_reset(void *cookie, uint32_t *cells, int on) 1514 { 1515 struct rkclock_softc *sc = cookie; 1516 uint32_t idx = cells[0]; 1517 uint32_t mask = (1 << (idx % 16)); 1518 1519 HWRITE4(sc, RK3308_CRU_SOFTRST_CON(idx / 16), 1520 mask << 16 | (on ? mask : 0)); 1521 } 1522 1523 1524 /* 1525 * Rockchip RK3328 1526 */ 1527 1528 const struct rkclock rk3328_clocks[] = { 1529 { 1530 RK3328_CLK_RTC32K, RK3328_CRU_CLKSEL_CON(38), 1531 SEL(15, 14), DIV(13, 0), 1532 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_XIN24M } 1533 }, 1534 { 1535 RK3328_CLK_SDMMC, RK3328_CRU_CLKSEL_CON(30), 1536 SEL(9, 8), DIV(7, 0), 1537 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_XIN24M, 1538 RK3328_USB480M } 1539 }, 1540 { 1541 RK3328_CLK_SDIO, RK3328_CRU_CLKSEL_CON(31), 1542 SEL(9, 8), DIV(7, 0), 1543 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_XIN24M, 1544 RK3328_USB480M } 1545 }, 1546 { 1547 RK3328_CLK_EMMC, RK3328_CRU_CLKSEL_CON(32), 1548 SEL(9, 8), DIV(7, 0), 1549 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_XIN24M, 1550 RK3328_USB480M } 1551 }, 1552 { 1553 RK3328_CLK_TSADC, RK3328_CRU_CLKSEL_CON(22), 1554 0, DIV(9, 0), 1555 { RK3328_CLK_24M } 1556 }, 1557 { 1558 RK3328_CLK_UART0, RK3328_CRU_CLKSEL_CON(14), 1559 SEL(9, 8), 0, 1560 { 0, 0, RK3328_XIN24M, RK3328_XIN24M } 1561 }, 1562 { 1563 RK3328_CLK_UART1, RK3328_CRU_CLKSEL_CON(16), 1564 SEL(9, 8), 0, 1565 { 0, 0, RK3328_XIN24M, RK3328_XIN24M } 1566 }, 1567 { 1568 RK3328_CLK_UART2, RK3328_CRU_CLKSEL_CON(18), 1569 SEL(9, 8), 0, 1570 { 0, 0, RK3328_XIN24M, RK3328_XIN24M } 1571 }, 1572 { 1573 RK3328_CLK_WIFI, RK3328_CRU_CLKSEL_CON(52), 1574 SEL(7, 6), DIV(5, 0), 1575 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_USB480M } 1576 }, 1577 { 1578 RK3328_CLK_I2C0, RK3328_CRU_CLKSEL_CON(34), 1579 SEL(7, 7), DIV(6, 0), 1580 { RK3328_PLL_CPLL, RK3328_PLL_GPLL } 1581 }, 1582 { 1583 RK3328_CLK_I2C1, RK3328_CRU_CLKSEL_CON(34), 1584 SEL(15, 15), DIV(14, 8), 1585 { RK3328_PLL_CPLL, RK3328_PLL_GPLL } 1586 }, 1587 { 1588 RK3328_CLK_I2C2, RK3328_CRU_CLKSEL_CON(35), 1589 SEL(7, 7), DIV(6, 0), 1590 { RK3328_PLL_CPLL, RK3328_PLL_GPLL } 1591 }, 1592 { 1593 RK3328_CLK_I2C3, RK3328_CRU_CLKSEL_CON(35), 1594 SEL(15, 15), DIV(14, 8), 1595 { RK3328_PLL_CPLL, RK3328_PLL_GPLL } 1596 }, 1597 { 1598 RK3328_CLK_CRYPTO, RK3328_CRU_CLKSEL_CON(20), 1599 SEL(7, 7), DIV(4, 0), 1600 { RK3328_PLL_CPLL, RK3328_PLL_GPLL } 1601 }, 1602 { 1603 RK3328_CLK_PDM, RK3328_CRU_CLKSEL_CON(20), 1604 SEL(15, 14), DIV(12, 8), 1605 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_PLL_APLL }, 1606 FIXED_PARENT | SET_PARENT 1607 }, 1608 { 1609 RK3328_CLK_VDEC_CABAC, RK3328_CRU_CLKSEL_CON(48), 1610 SEL(15, 14), DIV(12, 8), 1611 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY, 1612 RK3328_USB480M } 1613 }, 1614 { 1615 RK3328_CLK_VDEC_CORE, RK3328_CRU_CLKSEL_CON(49), 1616 SEL(7, 6), DIV(4, 0), 1617 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY, 1618 RK3328_USB480M } 1619 }, 1620 { 1621 RK3328_CLK_VENC_DSP, RK3328_CRU_CLKSEL_CON(52), 1622 SEL(15, 14), DIV(12, 8), 1623 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY, 1624 RK3328_USB480M } 1625 }, 1626 { 1627 RK3328_CLK_VENC_CORE, RK3328_CRU_CLKSEL_CON(51), 1628 SEL(15, 14), DIV(12, 8), 1629 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY, 1630 RK3328_USB480M } 1631 }, 1632 { 1633 RK3328_CLK_TSP, RK3328_CRU_CLKSEL_CON(21), 1634 SEL(15, 15), DIV(12, 8), 1635 { RK3328_PLL_CPLL, RK3328_PLL_GPLL } 1636 }, 1637 { 1638 RK3328_CLK_MAC2IO_SRC, RK3328_CRU_CLKSEL_CON(27), 1639 SEL(7, 7), DIV(4, 0), 1640 { RK3328_PLL_CPLL, RK3328_PLL_GPLL } 1641 }, 1642 { 1643 RK3328_DCLK_LCDC, RK3328_CRU_CLKSEL_CON(40), 1644 SEL(1, 1), 0, 1645 { RK3328_HDMIPHY, RK3328_DCLK_LCDC_SRC } 1646 }, 1647 { 1648 RK3328_ACLK_VOP_PRE, RK3328_CRU_CLKSEL_CON(39), 1649 SEL(7, 6), DIV(4, 0), 1650 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY, 1651 RK3328_USB480M } 1652 }, 1653 { 1654 RK3328_ACLK_RGA_PRE, RK3328_CRU_CLKSEL_CON(36), 1655 SEL(15, 14), DIV(12, 8), 1656 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY, 1657 RK3328_USB480M } 1658 }, 1659 { 1660 RK3328_ACLK_BUS_PRE, RK3328_CRU_CLKSEL_CON(0), 1661 SEL(14, 13), DIV(12, 8), 1662 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY } 1663 }, 1664 { 1665 RK3328_ACLK_PERI_PRE, RK3328_CRU_CLKSEL_CON(28), 1666 SEL(7, 6), DIV(4, 0), 1667 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY } 1668 }, 1669 { 1670 RK3328_ACLK_RKVDEC_PRE, RK3328_CRU_CLKSEL_CON(48), 1671 SEL(7, 6), DIV(4, 0), 1672 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY, 1673 RK3328_USB480M } 1674 }, 1675 { 1676 RK3328_ACLK_RKVENC, RK3328_CRU_CLKSEL_CON(51), 1677 SEL(7, 6), DIV(4, 0), 1678 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY, 1679 RK3328_USB480M } 1680 }, 1681 { 1682 RK3328_ACLK_VPU_PRE, RK3328_CRU_CLKSEL_CON(50), 1683 SEL(7, 6), DIV(4, 0), 1684 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY, 1685 RK3328_USB480M } 1686 }, 1687 { 1688 RK3328_ACLK_VIO_PRE, RK3328_CRU_CLKSEL_CON(37), 1689 SEL(7, 6), DIV(4, 0), 1690 { RK3328_PLL_CPLL, RK3328_PLL_GPLL, RK3328_HDMIPHY, 1691 RK3328_USB480M } 1692 }, 1693 { 1694 RK3328_PCLK_BUS_PRE, RK3328_CRU_CLKSEL_CON(1), 1695 0, DIV(14, 12), 1696 { RK3328_ACLK_BUS_PRE } 1697 }, 1698 { 1699 RK3328_HCLK_BUS_PRE, RK3328_CRU_CLKSEL_CON(1), 1700 0, DIV(9, 8), 1701 { RK3328_ACLK_BUS_PRE } 1702 }, 1703 { 1704 RK3328_PCLK_PERI, RK3328_CRU_CLKSEL_CON(29), 1705 0, DIV(6, 4), 1706 { RK3328_ACLK_PERI_PRE } 1707 }, 1708 { 1709 RK3328_HCLK_PERI, RK3328_CRU_CLKSEL_CON(29), 1710 0, DIV(1, 0), 1711 { RK3328_ACLK_PERI_PRE } 1712 }, 1713 { 1714 RK3328_CLK_24M, RK3328_CRU_CLKSEL_CON(2), 1715 0, DIV(12, 8), 1716 { RK3328_XIN24M } 1717 }, 1718 { 1719 /* Sentinel */ 1720 } 1721 }; 1722 1723 void 1724 rk3328_init(struct rkclock_softc *sc) 1725 { 1726 int i; 1727 1728 /* The code below assumes all clocks are enabled. Check this!. */ 1729 for (i = 0; i <= 28; i++) { 1730 if (HREAD4(sc, RK3328_CRU_CLKGATE_CON(i)) != 0x00000000) { 1731 printf("CRU_CLKGATE_CON%d: 0x%08x\n", i, 1732 HREAD4(sc, RK3328_CRU_CLKGATE_CON(i))); 1733 } 1734 } 1735 1736 sc->sc_clocks = rk3328_clocks; 1737 } 1738 1739 uint32_t 1740 rk3328_armclk_parent(uint32_t mux) 1741 { 1742 switch (mux) { 1743 case 0: 1744 return RK3328_PLL_APLL; 1745 case 1: 1746 return RK3328_PLL_GPLL; 1747 case 2: 1748 return RK3328_PLL_DPLL; 1749 case 3: 1750 return RK3328_PLL_NPLL; 1751 } 1752 1753 return 0; 1754 } 1755 1756 uint32_t 1757 rk3328_get_armclk(struct rkclock_softc *sc) 1758 { 1759 uint32_t reg, mux, div_con; 1760 uint32_t idx; 1761 1762 reg = HREAD4(sc, RK3328_CRU_CLKSEL_CON(0)); 1763 mux = (reg & RK3328_CRU_CORE_CLK_PLL_SEL_MASK) >> 1764 RK3328_CRU_CORE_CLK_PLL_SEL_SHIFT; 1765 div_con = (reg & RK3328_CRU_CLK_CORE_DIV_CON_MASK) >> 1766 RK3328_CRU_CLK_CORE_DIV_CON_SHIFT; 1767 idx = rk3328_armclk_parent(mux); 1768 1769 return rk3328_get_frequency(sc, &idx) / (div_con + 1); 1770 } 1771 1772 int 1773 rk3328_set_armclk(struct rkclock_softc *sc, uint32_t freq) 1774 { 1775 uint32_t reg, mux; 1776 uint32_t old_freq, div; 1777 uint32_t idx; 1778 1779 old_freq = rk3328_get_armclk(sc); 1780 if (freq == old_freq) 1781 return 0; 1782 1783 reg = HREAD4(sc, RK3328_CRU_CLKSEL_CON(0)); 1784 mux = (reg & RK3328_CRU_CORE_CLK_PLL_SEL_MASK) >> 1785 RK3328_CRU_CORE_CLK_PLL_SEL_SHIFT; 1786 1787 /* Keep the pclk_dbg clock at or below 300 MHz. */ 1788 div = 1; 1789 while (freq / (div + 1) > 300000000) 1790 div++; 1791 /* and make sure we use an odd divider. */ 1792 if ((div % 2) == 0) 1793 div++; 1794 1795 /* When ramping up, set clock dividers first. */ 1796 if (freq > old_freq) { 1797 HWRITE4(sc, RK3328_CRU_CLKSEL_CON(0), 1798 RK3328_CRU_CLK_CORE_DIV_CON_MASK << 16 | 1799 0 << RK3328_CRU_CLK_CORE_DIV_CON_SHIFT); 1800 HWRITE4(sc, RK3328_CRU_CLKSEL_CON(1), 1801 RK3328_CRU_ACLK_CORE_DIV_CON_MASK << 16 | 1802 1 << RK3328_CRU_ACLK_CORE_DIV_CON_SHIFT | 1803 RK3328_CRU_CLK_CORE_DBG_DIV_CON_MASK << 16 | 1804 div << RK3328_CRU_CLK_CORE_DBG_DIV_CON_SHIFT); 1805 } 1806 1807 /* We always use NPLL and force the switch below if needed. */ 1808 idx = RK3328_PLL_NPLL; 1809 rk3328_set_frequency(sc, &idx, freq); 1810 1811 /* When ramping down, set clock dividers last. */ 1812 if (freq < old_freq || mux != 3) { 1813 HWRITE4(sc, RK3328_CRU_CLKSEL_CON(0), 1814 RK3328_CRU_CORE_CLK_PLL_SEL_MASK << 16 | 1815 3 << RK3328_CRU_CORE_CLK_PLL_SEL_SHIFT | 1816 RK3328_CRU_CLK_CORE_DIV_CON_MASK << 16 | 1817 0 << RK3328_CRU_CLK_CORE_DIV_CON_SHIFT); 1818 HWRITE4(sc, RK3328_CRU_CLKSEL_CON(1), 1819 RK3328_CRU_ACLK_CORE_DIV_CON_MASK << 16 | 1820 1 << RK3328_CRU_ACLK_CORE_DIV_CON_SHIFT | 1821 RK3328_CRU_CLK_CORE_DBG_DIV_CON_MASK << 16 | 1822 div << RK3328_CRU_CLK_CORE_DBG_DIV_CON_SHIFT); 1823 } 1824 1825 return 0; 1826 } 1827 1828 uint32_t 1829 rk3328_get_pll(struct rkclock_softc *sc, bus_size_t base) 1830 { 1831 uint32_t fbdiv, postdiv1, postdiv2, refdiv; 1832 uint32_t dsmpd, fracdiv; 1833 uint64_t frac = 0; 1834 uint32_t reg; 1835 1836 reg = HREAD4(sc, base + 0x0000); 1837 postdiv1 = (reg & RK3328_CRU_PLL_POSTDIV1_MASK) >> 1838 RK3328_CRU_PLL_POSTDIV1_SHIFT; 1839 fbdiv = (reg & RK3328_CRU_PLL_FBDIV_MASK) >> 1840 RK3328_CRU_PLL_FBDIV_SHIFT; 1841 reg = HREAD4(sc, base + 0x0004); 1842 dsmpd = (reg & RK3328_CRU_PLL_DSMPD); 1843 postdiv2 = (reg & RK3328_CRU_PLL_POSTDIV2_MASK) >> 1844 RK3328_CRU_PLL_POSTDIV2_SHIFT; 1845 refdiv = (reg & RK3328_CRU_PLL_REFDIV_MASK) >> 1846 RK3328_CRU_PLL_REFDIV_SHIFT; 1847 reg = HREAD4(sc, base + 0x0008); 1848 fracdiv = (reg & RK3328_CRU_PLL_FRACDIV_MASK) >> 1849 RK3328_CRU_PLL_FRACDIV_SHIFT; 1850 1851 if (dsmpd == 0) 1852 frac = (24000000ULL * fracdiv / refdiv) >> 24; 1853 return ((24000000ULL * fbdiv / refdiv) + frac) / postdiv1 / postdiv2; 1854 } 1855 1856 int 1857 rk3328_set_pll(struct rkclock_softc *sc, bus_size_t base, uint32_t freq) 1858 { 1859 uint32_t fbdiv, postdiv1, postdiv2, refdiv; 1860 int mode_shift = -1; 1861 1862 switch (base) { 1863 case RK3328_CRU_APLL_CON(0): 1864 mode_shift = 0; 1865 break; 1866 case RK3328_CRU_DPLL_CON(0): 1867 mode_shift = 4; 1868 break; 1869 case RK3328_CRU_CPLL_CON(0): 1870 mode_shift = 8; 1871 break; 1872 case RK3328_CRU_GPLL_CON(0): 1873 mode_shift = 12; 1874 break; 1875 case RK3328_CRU_NPLL_CON(0): 1876 mode_shift = 1; 1877 break; 1878 } 1879 KASSERT(mode_shift != -1); 1880 1881 /* 1882 * It is not clear whether all combinations of the clock 1883 * dividers result in a stable clock. Therefore this function 1884 * only supports a limited set of PLL clock rates. For now 1885 * this set covers all the CPU frequencies supported by the 1886 * Linux kernel. 1887 */ 1888 switch (freq) { 1889 case 1800000000U: 1890 case 1704000000U: 1891 case 1608000000U: 1892 case 1512000000U: 1893 case 1488000000U: 1894 case 1416000000U: 1895 case 1392000000U: 1896 case 1296000000U: 1897 case 1200000000U: 1898 case 1104000000U: 1899 postdiv1 = postdiv2 = refdiv = 1; 1900 break; 1901 case 1008000000U: 1902 case 912000000U: 1903 case 816000000U: 1904 case 696000000U: 1905 postdiv1 = 2; postdiv2 = refdiv = 1; 1906 break; 1907 case 600000000U: 1908 postdiv1 = 3; postdiv2 = refdiv = 1; 1909 break; 1910 case 408000000U: 1911 case 312000000U: 1912 postdiv1 = postdiv2 = 2; refdiv = 1; 1913 break; 1914 case 216000000U: 1915 postdiv1 = 4; postdiv2 = 2; refdiv = 1; 1916 break; 1917 case 96000000U: 1918 postdiv1 = postdiv2 = 4; refdiv = 1; 1919 break; 1920 default: 1921 printf("%s: %u Hz\n", __func__, freq); 1922 return -1; 1923 } 1924 1925 /* Calculate feedback divider. */ 1926 fbdiv = freq * postdiv1 * postdiv2 * refdiv / 24000000; 1927 1928 /* 1929 * Select slow mode to guarantee a stable clock while we're 1930 * adjusting the PLL. 1931 */ 1932 HWRITE4(sc, RK3328_CRU_CRU_MODE, 1933 (RK3328_CRU_CRU_MODE_MASK << 16 | 1934 RK3328_CRU_CRU_MODE_SLOW) << mode_shift); 1935 1936 /* Set PLL rate. */ 1937 HWRITE4(sc, base + 0x0000, 1938 RK3328_CRU_PLL_POSTDIV1_MASK << 16 | 1939 postdiv1 << RK3328_CRU_PLL_POSTDIV1_SHIFT | 1940 RK3328_CRU_PLL_FBDIV_MASK << 16 | 1941 fbdiv << RK3328_CRU_PLL_FBDIV_SHIFT); 1942 HWRITE4(sc, base + 0x0004, 1943 RK3328_CRU_PLL_DSMPD << 16 | RK3328_CRU_PLL_DSMPD | 1944 RK3328_CRU_PLL_POSTDIV2_MASK << 16 | 1945 postdiv2 << RK3328_CRU_PLL_POSTDIV2_SHIFT | 1946 RK3328_CRU_PLL_REFDIV_MASK << 16 | 1947 refdiv << RK3328_CRU_PLL_REFDIV_SHIFT); 1948 1949 /* Wait for PLL to stabilize. */ 1950 while ((HREAD4(sc, base + 0x0004) & RK3328_CRU_PLL_PLL_LOCK) == 0) 1951 delay(10); 1952 1953 /* Switch back to normal mode. */ 1954 HWRITE4(sc, RK3328_CRU_CRU_MODE, 1955 (RK3328_CRU_CRU_MODE_MASK << 16 | 1956 RK3328_CRU_CRU_MODE_NORMAL) << mode_shift); 1957 1958 return 0; 1959 } 1960 1961 int 1962 rk3328_set_frac_pll(struct rkclock_softc *sc, bus_size_t base, uint32_t freq) 1963 { 1964 uint32_t fbdiv, postdiv1, postdiv2, refdiv, fracdiv; 1965 int mode_shift = -1; 1966 uint32_t reg; 1967 1968 switch (base) { 1969 case RK3328_CRU_APLL_CON(0): 1970 mode_shift = 0; 1971 break; 1972 case RK3328_CRU_DPLL_CON(0): 1973 mode_shift = 4; 1974 break; 1975 case RK3328_CRU_CPLL_CON(0): 1976 mode_shift = 8; 1977 break; 1978 case RK3328_CRU_GPLL_CON(0): 1979 mode_shift = 12; 1980 break; 1981 case RK3328_CRU_NPLL_CON(0): 1982 mode_shift = 1; 1983 break; 1984 } 1985 KASSERT(mode_shift != -1); 1986 1987 /* 1988 * It is not clear whether all combinations of the clock 1989 * dividers result in a stable clock. Therefore this function 1990 * only supports a limited set of PLL clock rates. This set 1991 * set covers all the fractional PLL frequencies supported by 1992 * the Linux kernel. 1993 */ 1994 switch (freq) { 1995 case 1016064000U: 1996 postdiv1 = postdiv2 = 1; refdiv = 3; fracdiv = 134217; 1997 break; 1998 case 983040000U: 1999 postdiv1 = postdiv2 = 1; refdiv = 24; fracdiv = 671088; 2000 break; 2001 case 491520000U: 2002 postdiv1 = 2; postdiv2 = 1; refdiv = 24; fracdiv = 671088; 2003 break; 2004 case 61440000U: 2005 postdiv1 = 7; postdiv2 = 2; refdiv = 6; fracdiv = 671088; 2006 break; 2007 case 56448000U: 2008 postdiv1 = postdiv2 = 4; refdiv = 12; fracdiv = 9797894; 2009 break; 2010 case 40960000U: 2011 postdiv1 = 4; postdiv2 = 5; refdiv = 12; fracdiv = 10066239; 2012 break; 2013 default: 2014 printf("%s: %u Hz\n", __func__, freq); 2015 return -1; 2016 } 2017 2018 /* Calculate feedback divider. */ 2019 fbdiv = (uint64_t)freq * postdiv1 * postdiv2 * refdiv / 24000000; 2020 2021 /* 2022 * Select slow mode to guarantee a stable clock while we're 2023 * adjusting the PLL. 2024 */ 2025 HWRITE4(sc, RK3328_CRU_CRU_MODE, 2026 (RK3328_CRU_CRU_MODE_MASK << 16 | 2027 RK3328_CRU_CRU_MODE_SLOW) << mode_shift); 2028 2029 /* Set PLL rate. */ 2030 HWRITE4(sc, base + 0x0000, 2031 RK3328_CRU_PLL_POSTDIV1_MASK << 16 | 2032 postdiv1 << RK3328_CRU_PLL_POSTDIV1_SHIFT | 2033 RK3328_CRU_PLL_FBDIV_MASK << 16 | 2034 fbdiv << RK3328_CRU_PLL_FBDIV_SHIFT); 2035 HWRITE4(sc, base + 0x0004, 2036 RK3328_CRU_PLL_DSMPD << 16 | 2037 RK3328_CRU_PLL_POSTDIV2_MASK << 16 | 2038 postdiv2 << RK3328_CRU_PLL_POSTDIV2_SHIFT | 2039 RK3328_CRU_PLL_REFDIV_MASK << 16 | 2040 refdiv << RK3328_CRU_PLL_REFDIV_SHIFT); 2041 reg = HREAD4(sc, base + 0x0008); 2042 reg &= ~RK3328_CRU_PLL_FRACDIV_MASK; 2043 reg |= fracdiv << RK3328_CRU_PLL_FRACDIV_SHIFT; 2044 HWRITE4(sc, base + 0x0008, reg); 2045 2046 /* Wait for PLL to stabilize. */ 2047 while ((HREAD4(sc, base + 0x0004) & RK3328_CRU_PLL_PLL_LOCK) == 0) 2048 delay(10); 2049 2050 /* Switch back to normal mode. */ 2051 HWRITE4(sc, RK3328_CRU_CRU_MODE, 2052 (RK3328_CRU_CRU_MODE_MASK << 16 | 2053 RK3328_CRU_CRU_MODE_NORMAL) << mode_shift); 2054 2055 return 0; 2056 } 2057 2058 uint32_t 2059 rk3328_get_frequency(void *cookie, uint32_t *cells) 2060 { 2061 struct rkclock_softc *sc = cookie; 2062 uint32_t idx = cells[0]; 2063 uint32_t reg; 2064 2065 switch (idx) { 2066 case RK3328_PLL_APLL: 2067 return rk3328_get_pll(sc, RK3328_CRU_APLL_CON(0)); 2068 case RK3328_PLL_DPLL: 2069 return rk3328_get_pll(sc, RK3328_CRU_DPLL_CON(0)); 2070 case RK3328_PLL_CPLL: 2071 return rk3328_get_pll(sc, RK3328_CRU_CPLL_CON(0)); 2072 case RK3328_PLL_GPLL: 2073 return rk3328_get_pll(sc, RK3328_CRU_GPLL_CON(0)); 2074 case RK3328_PLL_NPLL: 2075 return rk3328_get_pll(sc, RK3328_CRU_NPLL_CON(0)); 2076 case RK3328_ARMCLK: 2077 return rk3328_get_armclk(sc); 2078 case RK3328_XIN24M: 2079 return 24000000; 2080 case RK3328_GMAC_CLKIN: 2081 return 125000000; 2082 /* 2083 * XXX The HDMIPHY and USB480M clocks are external. Returning 2084 * zero here will cause them to be ignored for reparenting 2085 * purposes. 2086 */ 2087 case RK3328_HDMIPHY: 2088 return 0; 2089 case RK3328_USB480M: 2090 return 0; 2091 case RK3328_CLK_MAC2IO: 2092 reg = regmap_read_4(sc->sc_grf, RK3328_GRF_MAC_CON1); 2093 if (reg & RK3328_GRF_GMAC2IO_RMII_EXTCLK_SEL) 2094 idx = RK3328_GMAC_CLKIN; 2095 else 2096 idx = RK3328_CLK_MAC2IO_SRC; 2097 return rk3328_get_frequency(sc, &idx); 2098 default: 2099 break; 2100 } 2101 2102 return rkclock_get_frequency(sc, idx); 2103 } 2104 2105 int 2106 rk3328_set_frequency(void *cookie, uint32_t *cells, uint32_t freq) 2107 { 2108 struct rkclock_softc *sc = cookie; 2109 uint32_t idx = cells[0]; 2110 uint32_t reg, mux; 2111 2112 switch (idx) { 2113 case RK3328_PLL_APLL: 2114 return rk3328_set_frac_pll(sc, RK3328_CRU_APLL_CON(0), freq); 2115 case RK3328_PLL_DPLL: 2116 return rk3328_set_pll(sc, RK3328_CRU_DPLL_CON(0), freq); 2117 case RK3328_PLL_CPLL: 2118 return rk3328_set_pll(sc, RK3328_CRU_CPLL_CON(0), freq); 2119 case RK3328_PLL_GPLL: 2120 return rk3328_set_frac_pll(sc, RK3328_CRU_GPLL_CON(0), freq); 2121 case RK3328_PLL_NPLL: 2122 return rk3328_set_pll(sc, RK3328_CRU_NPLL_CON(0), freq); 2123 case RK3328_ARMCLK: 2124 return rk3328_set_armclk(sc, freq); 2125 case RK3328_CLK_UART0: 2126 case RK3328_CLK_UART1: 2127 case RK3328_CLK_UART2: 2128 if (freq == rk3328_get_frequency(sc, &idx)) 2129 return 0; 2130 break; 2131 case RK3328_DCLK_LCDC: 2132 reg = HREAD4(sc, RK3328_CRU_CLKSEL_CON(40)); 2133 mux = (reg & RK3328_CRU_VOP_DCLK_SRC_SEL_MASK) >> 2134 RK3328_CRU_VOP_DCLK_SRC_SEL_SHIFT; 2135 idx = (mux == 0) ? RK3328_HDMIPHY : RK3328_DCLK_LCDC_SRC; 2136 return rk3328_set_frequency(sc, &idx, freq); 2137 case RK3328_HCLK_CRYPTO_SLV: 2138 idx = RK3328_HCLK_BUS_PRE; 2139 return rk3328_set_frequency(sc, &idx, freq); 2140 default: 2141 break; 2142 } 2143 2144 return rkclock_set_frequency(sc, idx, freq); 2145 } 2146 2147 int 2148 rk3328_set_parent(void *cookie, uint32_t *cells, uint32_t *pcells) 2149 { 2150 struct rkclock_softc *sc = cookie; 2151 uint32_t idx = cells[0]; 2152 uint32_t parent; 2153 2154 if (pcells[0] == sc->sc_phandle) 2155 parent = pcells[1]; 2156 else { 2157 char name[32]; 2158 int node; 2159 2160 node = OF_getnodebyphandle(pcells[0]); 2161 if (node == 0) 2162 return -1; 2163 name[0] = 0; 2164 OF_getprop(node, "clock-output-names", name, sizeof(name)); 2165 name[sizeof(name) - 1] = 0; 2166 if (strcmp(name, "xin24m") == 0) 2167 parent = RK3328_XIN24M; 2168 else if (strcmp(name, "gmac_clkin") == 0) 2169 parent = RK3328_GMAC_CLKIN; 2170 else 2171 return -1; 2172 } 2173 2174 switch (idx) { 2175 case RK3328_CLK_MAC2IO: 2176 if (parent == RK3328_GMAC_CLKIN) { 2177 regmap_write_4(sc->sc_grf, RK3328_GRF_MAC_CON1, 2178 RK3328_GRF_GMAC2IO_RMII_EXTCLK_SEL << 16 | 2179 RK3328_GRF_GMAC2IO_RMII_EXTCLK_SEL); 2180 } else { 2181 regmap_write_4(sc->sc_grf, RK3328_GRF_MAC_CON1, 2182 RK3328_GRF_GMAC2IO_RMII_EXTCLK_SEL << 16); 2183 } 2184 return 0; 2185 case RK3328_CLK_MAC2IO_EXT: 2186 if (parent == RK3328_GMAC_CLKIN) { 2187 regmap_write_4(sc->sc_grf, RK3328_GRF_SOC_CON4, 2188 RK3328_GRF_GMAC2IO_MAC_CLK_OUTPUT_EN << 16 | 2189 RK3328_GRF_GMAC2IO_MAC_CLK_OUTPUT_EN); 2190 } else { 2191 regmap_write_4(sc->sc_grf, RK3328_GRF_SOC_CON4, 2192 RK3328_GRF_GMAC2IO_MAC_CLK_OUTPUT_EN << 16); 2193 } 2194 return 0; 2195 } 2196 2197 return rkclock_set_parent(sc, idx, parent); 2198 } 2199 2200 void 2201 rk3328_enable(void *cookie, uint32_t *cells, int on) 2202 { 2203 uint32_t idx = cells[0]; 2204 2205 /* 2206 * All clocks are enabled by default, so there is nothing for 2207 * us to do until we start disabling clocks. 2208 */ 2209 if (!on) 2210 printf("%s: 0x%08x\n", __func__, idx); 2211 } 2212 2213 void 2214 rk3328_reset(void *cookie, uint32_t *cells, int on) 2215 { 2216 struct rkclock_softc *sc = cookie; 2217 uint32_t idx = cells[0]; 2218 uint32_t mask = (1 << (idx % 16)); 2219 2220 HWRITE4(sc, RK3328_CRU_SOFTRST_CON(idx / 16), 2221 mask << 16 | (on ? mask : 0)); 2222 } 2223 2224 /* 2225 * Rockchip RK3399 2226 */ 2227 2228 const struct rkclock rk3399_clocks[] = { 2229 { 2230 RK3399_CLK_I2C1, RK3399_CRU_CLKSEL_CON(61), 2231 SEL(7, 7), DIV(6, 0), 2232 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 2233 }, 2234 { 2235 RK3399_CLK_I2C2, RK3399_CRU_CLKSEL_CON(62), 2236 SEL(7, 7), DIV(6, 0), 2237 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 2238 }, 2239 { 2240 RK3399_CLK_I2C3, RK3399_CRU_CLKSEL_CON(63), 2241 SEL(7, 7), DIV(6, 0), 2242 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 2243 }, 2244 { 2245 RK3399_CLK_I2C5, RK3399_CRU_CLKSEL_CON(61), 2246 SEL(15, 15), DIV(14, 8), 2247 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 2248 }, 2249 { 2250 RK3399_CLK_I2C6, RK3399_CRU_CLKSEL_CON(62), 2251 SEL(15, 15), DIV(14, 8), 2252 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 2253 }, 2254 { 2255 RK3399_CLK_I2C7, RK3399_CRU_CLKSEL_CON(63), 2256 SEL(15, 15), DIV(14, 8), 2257 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 2258 }, 2259 { 2260 RK3399_CLK_SDMMC, RK3399_CRU_CLKSEL_CON(16), 2261 SEL(10, 8), DIV(6, 0), 2262 { RK3399_PLL_CPLL, RK3399_PLL_GPLL, RK3399_PLL_NPLL, 2263 /* RK3399_PLL_PPLL */ 0, /* RK3399_USB_480M */ 0, 2264 RK3399_XIN24M } 2265 }, 2266 { 2267 RK3399_CLK_SDIO, RK3399_CRU_CLKSEL_CON(15), 2268 SEL(10, 8), DIV(6, 0), 2269 { RK3399_PLL_CPLL, RK3399_PLL_GPLL, RK3399_PLL_NPLL, 2270 /* RK3399_PLL_PPLL */ 0, /* RK3399_USB_480M */ 0, 2271 RK3399_XIN24M } 2272 }, 2273 { 2274 RK3399_CLK_EMMC, RK3399_CRU_CLKSEL_CON(22), 2275 SEL(10, 8), DIV(6, 0), 2276 { RK3399_PLL_CPLL, RK3399_PLL_GPLL, RK3399_PLL_NPLL, 2277 /* RK3399_USB_480M */ 0, RK3399_XIN24M } 2278 }, 2279 { 2280 RK3399_CLK_TSADC, RK3399_CRU_CLKSEL_CON(27), 2281 SEL(15, 15), DIV(9, 0), 2282 { RK3399_XIN24M, RK3399_CLK_32K } 2283 }, 2284 { 2285 RK3399_CLK_UART0, RK3399_CRU_CLKSEL_CON(33), 2286 SEL(9, 8), 0, 2287 { 0, 0, RK3399_XIN24M } 2288 }, 2289 { 2290 RK3399_CLK_UART1, RK3399_CRU_CLKSEL_CON(34), 2291 SEL(9, 8), 0, 2292 { 0, 0, RK3399_XIN24M } 2293 }, 2294 { 2295 RK3399_CLK_UART2, RK3399_CRU_CLKSEL_CON(35), 2296 SEL(9, 8), 0, 2297 { 0, 0, RK3399_XIN24M } 2298 }, 2299 { 2300 RK3399_CLK_UART3, RK3399_CRU_CLKSEL_CON(36), 2301 SEL(9, 8), 0, 2302 { 0, 0, RK3399_XIN24M } 2303 }, 2304 { 2305 RK3399_CLK_I2S0_8CH, RK3399_CRU_CLKSEL_CON(28), 2306 SEL(9, 8), 0, 2307 { RK3399_CLK_I2S0_DIV, RK3399_CLK_I2S0_FRAC, 0, RK3399_XIN12M }, 2308 SET_PARENT 2309 }, 2310 { 2311 RK3399_CLK_I2S1_8CH, RK3399_CRU_CLKSEL_CON(29), 2312 SEL(9, 8), 0, 2313 { RK3399_CLK_I2S1_DIV, RK3399_CLK_I2S1_FRAC, 0, RK3399_XIN12M }, 2314 SET_PARENT 2315 }, 2316 { 2317 RK3399_CLK_I2S2_8CH, RK3399_CRU_CLKSEL_CON(30), 2318 SEL(9, 8), 0, 2319 { RK3399_CLK_I2S2_DIV, RK3399_CLK_I2S2_FRAC, 0, RK3399_XIN12M }, 2320 SET_PARENT 2321 }, 2322 { 2323 RK3399_CLK_I2S_8CH_OUT, RK3399_CRU_CLKSEL_CON(31), 2324 SEL(2, 2), 0, 2325 { RK3399_CLK_I2SOUT_SRC, RK3399_XIN12M }, 2326 SET_PARENT 2327 }, 2328 { 2329 RK3399_CLK_MAC, RK3399_CRU_CLKSEL_CON(20), 2330 SEL(15, 14), DIV(12, 8), 2331 { RK3399_PLL_CPLL, RK3399_PLL_GPLL, RK3399_PLL_NPLL } 2332 }, 2333 { 2334 RK3399_CLK_UPHY0_TCPDCORE, RK3399_CRU_CLKSEL_CON(64), 2335 SEL(7, 6), DIV(4, 0), 2336 { RK3399_XIN24M, RK3399_CLK_32K, RK3399_PLL_CPLL, 2337 RK3399_PLL_GPLL } 2338 }, 2339 { 2340 RK3399_CLK_UPHY1_TCPDCORE, RK3399_CRU_CLKSEL_CON(65), 2341 SEL(7, 6), DIV(4, 0), 2342 { RK3399_XIN24M, RK3399_CLK_32K, RK3399_PLL_CPLL, 2343 RK3399_PLL_GPLL } 2344 }, 2345 { 2346 RK3399_CLK_PCIEPHY_REF, RK3399_CRU_CLKSEL_CON(18), 2347 SEL(10, 10), 0, 2348 { RK3399_XIN24M, RK3399_CLK_PCIEPHY_REF100M }, 2349 SET_PARENT 2350 }, 2351 { 2352 RK3399_CLK_PCIEPHY_REF100M, RK3399_CRU_CLKSEL_CON(18), 2353 0, DIV(15, 11), 2354 { RK3399_PLL_NPLL } 2355 }, 2356 { 2357 RK3399_DCLK_VOP0, RK3399_CRU_CLKSEL_CON(49), 2358 SEL(11, 11), 0, 2359 { RK3399_DCLK_VOP0_DIV, RK3399_DCLK_VOP0_FRAC }, 2360 SET_PARENT 2361 }, 2362 { 2363 RK3399_DCLK_VOP1, RK3399_CRU_CLKSEL_CON(50), 2364 SEL(11, 11), 0, 2365 { RK3399_DCLK_VOP1_DIV, RK3399_DCLK_VOP1_FRAC }, 2366 SET_PARENT 2367 }, 2368 { 2369 RK3399_DCLK_VOP0_DIV, RK3399_CRU_CLKSEL_CON(49), 2370 SEL(9, 8), DIV(7, 0), 2371 { RK3399_PLL_VPLL, RK3399_PLL_CPLL, RK3399_PLL_GPLL } 2372 }, 2373 { 2374 RK3399_DCLK_VOP1_DIV, RK3399_CRU_CLKSEL_CON(50), 2375 SEL(9, 8), DIV(7, 0), 2376 { RK3399_PLL_VPLL, RK3399_PLL_CPLL, RK3399_PLL_GPLL } 2377 }, 2378 { 2379 RK3399_ACLK_PERIPH, RK3399_CRU_CLKSEL_CON(14), 2380 SEL(7, 7), DIV(4, 0), 2381 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 2382 }, 2383 { 2384 RK3399_ACLK_PERILP0, RK3399_CRU_CLKSEL_CON(23), 2385 SEL(7, 7), DIV(4, 0), 2386 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 2387 }, 2388 { 2389 RK3399_ACLK_VIO, RK3399_CRU_CLKSEL_CON(42), 2390 SEL(7, 6), DIV(4, 0), 2391 { RK3399_PLL_CPLL, RK3399_PLL_GPLL, /* RK3399_PLL_PPLL */ } 2392 }, 2393 { 2394 RK3399_ACLK_CCI, RK3399_CRU_CLKSEL_CON(5), 2395 SEL(7, 6), DIV(4, 0), 2396 { RK3399_PLL_CPLL, RK3399_PLL_GPLL, RK3399_PLL_NPLL, 2397 RK3399_PLL_VPLL } 2398 }, 2399 { 2400 RK3399_ACLK_VOP0, RK3399_CRU_CLKSEL_CON(47), 2401 SEL(7, 6), DIV(4, 0), 2402 { RK3399_PLL_VPLL, RK3399_PLL_CPLL, RK3399_PLL_GPLL, 2403 RK3399_PLL_NPLL } 2404 }, 2405 { 2406 RK3399_ACLK_VOP1, RK3399_CRU_CLKSEL_CON(48), 2407 SEL(7, 6), DIV(4, 0), 2408 { RK3399_PLL_VPLL, RK3399_PLL_CPLL, RK3399_PLL_GPLL, 2409 RK3399_PLL_NPLL } 2410 }, 2411 { 2412 RK3399_ACLK_HDCP, RK3399_CRU_CLKSEL_CON(42), 2413 SEL(15, 14), DIV(12, 8), 2414 { RK3399_PLL_CPLL, RK3399_PLL_GPLL, /* RK3399_PLL_PPLL */ } 2415 }, 2416 { 2417 RK3399_ACLK_GIC_PRE, RK3399_CRU_CLKSEL_CON(56), 2418 SEL(15, 15), DIV(12, 8), 2419 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 2420 }, 2421 { 2422 RK3399_PCLK_PERIPH, RK3399_CRU_CLKSEL_CON(14), 2423 0, DIV(14, 12), 2424 { RK3399_ACLK_PERIPH } 2425 }, 2426 { 2427 RK3399_PCLK_PERILP0, RK3399_CRU_CLKSEL_CON(23), 2428 0, DIV(14, 12), 2429 { RK3399_ACLK_PERILP0 } 2430 }, 2431 { 2432 RK3399_PCLK_PERILP1, RK3399_CRU_CLKSEL_CON(25), 2433 0, DIV(10, 8), 2434 { RK3399_HCLK_PERILP1 } 2435 }, 2436 { 2437 RK3399_PCLK_DDR, RK3399_CRU_CLKSEL_CON(6), 2438 SEL(15, 15), DIV(12, 8), 2439 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 2440 }, 2441 { 2442 RK3399_PCLK_WDT, RK3399_CRU_CLKSEL_CON(57), 2443 0, DIV(4, 0), 2444 { RK3399_PLL_GPLL } 2445 }, 2446 { 2447 RK3399_HCLK_PERIPH, RK3399_CRU_CLKSEL_CON(14), 2448 0, DIV(9, 8), 2449 { RK3399_ACLK_PERIPH } 2450 }, 2451 { 2452 RK3399_HCLK_PERILP0, RK3399_CRU_CLKSEL_CON(23), 2453 0, DIV(9, 8), 2454 { RK3399_ACLK_PERILP0 } 2455 }, 2456 { 2457 RK3399_HCLK_PERILP1, RK3399_CRU_CLKSEL_CON(25), 2458 SEL(7, 7), DIV(4, 0), 2459 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 2460 }, 2461 { 2462 RK3399_HCLK_SDMMC, RK3399_CRU_CLKSEL_CON(13), 2463 SEL(15, 15), DIV(12, 8), 2464 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 2465 }, 2466 { 2467 RK3399_HCLK_VOP0, RK3399_CRU_CLKSEL_CON(47), 2468 0, DIV(12, 8), 2469 { RK3399_ACLK_VOP0 } 2470 }, 2471 { 2472 RK3399_HCLK_VOP1, RK3399_CRU_CLKSEL_CON(48), 2473 0, DIV(12, 8), 2474 { RK3399_ACLK_VOP1 } 2475 }, 2476 { 2477 RK3399_CLK_I2S0_DIV, RK3399_CRU_CLKSEL_CON(28), 2478 SEL(7, 7), DIV(6, 0), 2479 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 2480 }, 2481 { 2482 RK3399_CLK_I2S1_DIV, RK3399_CRU_CLKSEL_CON(29), 2483 SEL(7, 7), DIV(6, 0), 2484 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 2485 }, 2486 { 2487 RK3399_CLK_I2S2_DIV, RK3399_CRU_CLKSEL_CON(30), 2488 SEL(7, 7), DIV(6, 0), 2489 { RK3399_PLL_CPLL, RK3399_PLL_GPLL } 2490 }, 2491 { 2492 RK3399_CLK_I2SOUT_SRC, RK3399_CRU_CLKSEL_CON(31), 2493 SEL(1, 0), 0, 2494 { RK3399_CLK_I2S0_8CH, RK3399_CLK_I2S1_8CH, 2495 RK3399_CLK_I2S2_8CH }, 2496 SET_PARENT 2497 }, 2498 { 2499 /* Sentinel */ 2500 } 2501 }; 2502 2503 /* Some of our parent clocks live in the PMUCRU. */ 2504 struct rkclock_softc *rk3399_pmucru_sc; 2505 2506 void 2507 rk3399_init(struct rkclock_softc *sc) 2508 { 2509 int i; 2510 2511 /* PMUCRU instance should attach before us. */ 2512 KASSERT(rk3399_pmucru_sc != NULL); 2513 2514 /* 2515 * The U-Boot shipped on the Theobroma Systems RK3399-Q7 2516 * module is buggy and sets the parent of the clock for the 2517 * "big" cluster to LPLL. Undo that mistake here such that 2518 * the clocks of both clusters are independent. 2519 */ 2520 HWRITE4(sc, RK3399_CRU_CLKSEL_CON(2), 2521 RK3399_CRU_CORE_PLL_SEL_MASK << 16 | 2522 RK3399_CRU_CORE_PLL_SEL_BPLL); 2523 2524 /* The code below assumes all clocks are enabled. Check this!. */ 2525 for (i = 0; i <= 34; i++) { 2526 if (HREAD4(sc, RK3399_CRU_CLKGATE_CON(i)) != 0x00000000) { 2527 printf("CRU_CLKGATE_CON%d: 0x%08x\n", i, 2528 HREAD4(sc, RK3399_CRU_CLKGATE_CON(i))); 2529 } 2530 } 2531 2532 sc->sc_clocks = rk3399_clocks; 2533 } 2534 2535 uint32_t 2536 rk3399_get_pll(struct rkclock_softc *sc, bus_size_t base) 2537 { 2538 uint32_t fbdiv, postdiv1, postdiv2, refdiv; 2539 uint32_t pll_work_mode; 2540 uint32_t reg; 2541 2542 reg = HREAD4(sc, base + 0x000c); 2543 pll_work_mode = reg & RK3399_CRU_PLL_PLL_WORK_MODE_MASK; 2544 if (pll_work_mode == RK3399_CRU_PLL_PLL_WORK_MODE_SLOW) 2545 return 24000000; 2546 if (pll_work_mode == RK3399_CRU_PLL_PLL_WORK_MODE_DEEP_SLOW) 2547 return 32768; 2548 2549 reg = HREAD4(sc, base + 0x0000); 2550 fbdiv = (reg & RK3399_CRU_PLL_FBDIV_MASK) >> 2551 RK3399_CRU_PLL_FBDIV_SHIFT; 2552 reg = HREAD4(sc, base + 0x0004); 2553 postdiv2 = (reg & RK3399_CRU_PLL_POSTDIV2_MASK) >> 2554 RK3399_CRU_PLL_POSTDIV2_SHIFT; 2555 postdiv1 = (reg & RK3399_CRU_PLL_POSTDIV1_MASK) >> 2556 RK3399_CRU_PLL_POSTDIV1_SHIFT; 2557 refdiv = (reg & RK3399_CRU_PLL_REFDIV_MASK) >> 2558 RK3399_CRU_PLL_REFDIV_SHIFT; 2559 return 24000000ULL * fbdiv / refdiv / postdiv1 / postdiv2; 2560 } 2561 2562 int 2563 rk3399_set_pll(struct rkclock_softc *sc, bus_size_t base, uint32_t freq) 2564 { 2565 uint32_t fbdiv, postdiv1, postdiv2, refdiv; 2566 2567 /* 2568 * It is not clear whether all combinations of the clock 2569 * dividers result in a stable clock. Therefore this function 2570 * only supports a limited set of PLL clock rates. For now 2571 * this set covers all the CPU frequencies supported by the 2572 * Linux kernel. 2573 */ 2574 switch (freq) { 2575 case 2208000000U: 2576 case 2184000000U: 2577 case 2088000000U: 2578 case 2040000000U: 2579 case 2016000000U: 2580 case 1992000000U: 2581 case 1896000000U: 2582 case 1800000000U: 2583 case 1704000000U: 2584 case 1608000000U: 2585 case 1512000000U: 2586 case 1488000000U: 2587 case 1416000000U: 2588 case 1200000000U: 2589 postdiv1 = postdiv2 = refdiv = 1; 2590 break; 2591 case 1008000000U: 2592 case 816000000U: 2593 case 696000000U: 2594 postdiv1 = 2; postdiv2 = refdiv = 1; 2595 break; 2596 case 676000000U: 2597 postdiv1 = 2; postdiv2 = 1; refdiv = 3; 2598 break; 2599 case 1000000000U: 2600 case 800000000U: 2601 case 600000000U: 2602 postdiv1 = 3; postdiv2 = refdiv = 1; 2603 break; 2604 case 594000000U: 2605 postdiv1 = 4; postdiv2 = refdiv = 1; 2606 break; 2607 case 408000000U: 2608 postdiv1 = postdiv2 = 2; refdiv = 1; 2609 break; 2610 case 297000000U: 2611 case 216000000U: 2612 postdiv1 = 4; postdiv2 = 2; refdiv = 1; 2613 break; 2614 case 148500000U: 2615 case 96000000U: 2616 postdiv1 = postdiv2 = 4; refdiv = 1; 2617 break; 2618 case 74250000U: 2619 postdiv1 = postdiv2 = 4; refdiv = 2; 2620 break; 2621 case 65000000U: 2622 case 54000000U: 2623 case 27000000U: 2624 postdiv1 = 6; postdiv2 = 4; refdiv = 1; 2625 break; 2626 default: 2627 printf("%s: %d Hz\n", __func__, freq); 2628 return -1; 2629 } 2630 2631 /* Calculate feedback divider. */ 2632 fbdiv = freq * postdiv1 * postdiv2 * refdiv / 24000000; 2633 2634 /* 2635 * Select slow mode to guarantee a stable clock while we're 2636 * adjusting the PLL. 2637 */ 2638 HWRITE4(sc, base + 0x000c, 2639 RK3399_CRU_PLL_PLL_WORK_MODE_MASK << 16 | 2640 RK3399_CRU_PLL_PLL_WORK_MODE_SLOW); 2641 2642 /* Set PLL rate. */ 2643 HWRITE4(sc, base + 0x0000, 2644 RK3399_CRU_PLL_FBDIV_MASK << 16 | 2645 fbdiv << RK3399_CRU_PLL_FBDIV_SHIFT); 2646 HWRITE4(sc, base + 0x0004, 2647 RK3399_CRU_PLL_POSTDIV2_MASK << 16 | 2648 postdiv2 << RK3399_CRU_PLL_POSTDIV2_SHIFT | 2649 RK3399_CRU_PLL_POSTDIV1_MASK << 16 | 2650 postdiv1 << RK3399_CRU_PLL_POSTDIV1_SHIFT | 2651 RK3399_CRU_PLL_REFDIV_MASK << 16 | 2652 refdiv << RK3399_CRU_PLL_REFDIV_SHIFT); 2653 2654 /* Wait for PLL to stabilize. */ 2655 while ((HREAD4(sc, base + 0x0008) & RK3399_CRU_PLL_PLL_LOCK) == 0) 2656 delay(10); 2657 2658 /* Switch back to normal mode. */ 2659 HWRITE4(sc, base + 0x000c, 2660 RK3399_CRU_PLL_PLL_WORK_MODE_MASK << 16 | 2661 RK3399_CRU_PLL_PLL_WORK_MODE_NORMAL); 2662 2663 return 0; 2664 } 2665 2666 uint32_t 2667 rk3399_armclk_parent(uint32_t mux) 2668 { 2669 switch (mux) { 2670 case 0: 2671 return RK3399_PLL_ALPLL; 2672 case 1: 2673 return RK3399_PLL_ABPLL; 2674 case 2: 2675 return RK3399_PLL_DPLL; 2676 case 3: 2677 return RK3399_PLL_GPLL; 2678 } 2679 2680 return 0; 2681 } 2682 2683 uint32_t 2684 rk3399_get_armclk(struct rkclock_softc *sc, bus_size_t clksel) 2685 { 2686 uint32_t reg, mux, div_con; 2687 uint32_t idx; 2688 2689 reg = HREAD4(sc, clksel); 2690 mux = (reg & RK3399_CRU_CORE_PLL_SEL_MASK) >> 2691 RK3399_CRU_CORE_PLL_SEL_SHIFT; 2692 div_con = (reg & RK3399_CRU_CLK_CORE_DIV_CON_MASK) >> 2693 RK3399_CRU_CLK_CORE_DIV_CON_SHIFT; 2694 idx = rk3399_armclk_parent(mux); 2695 2696 return rk3399_get_frequency(sc, &idx) / (div_con + 1); 2697 } 2698 2699 int 2700 rk3399_set_armclk(struct rkclock_softc *sc, bus_size_t clksel, uint32_t freq) 2701 { 2702 uint32_t reg, mux; 2703 uint32_t old_freq, div; 2704 uint32_t idx; 2705 2706 old_freq = rk3399_get_armclk(sc, clksel); 2707 if (freq == old_freq) 2708 return 0; 2709 2710 reg = HREAD4(sc, clksel); 2711 mux = (reg & RK3399_CRU_CORE_PLL_SEL_MASK) >> 2712 RK3399_CRU_CORE_PLL_SEL_SHIFT; 2713 idx = rk3399_armclk_parent(mux); 2714 2715 /* Keep the atclk_core and pclk_dbg clocks at or below 200 MHz. */ 2716 div = 1; 2717 while (freq / (div + 1) > 200000000) 2718 div++; 2719 2720 /* When ramping up, set clock dividers first. */ 2721 if (freq > old_freq) { 2722 HWRITE4(sc, clksel, 2723 RK3399_CRU_CLK_CORE_DIV_CON_MASK << 16 | 2724 0 << RK3399_CRU_CLK_CORE_DIV_CON_SHIFT | 2725 RK3399_CRU_ACLKM_CORE_DIV_CON_MASK << 16 | 2726 1 << RK3399_CRU_ACLKM_CORE_DIV_CON_SHIFT); 2727 HWRITE4(sc, clksel + 0x0004, 2728 RK3399_CRU_PCLK_DBG_DIV_CON_MASK << 16 | 2729 div << RK3399_CRU_PCLK_DBG_DIV_CON_SHIFT | 2730 RK3399_CRU_ATCLK_CORE_DIV_CON_MASK << 16 | 2731 div << RK3399_CRU_ATCLK_CORE_DIV_CON_SHIFT); 2732 } 2733 2734 rk3399_set_frequency(sc, &idx, freq); 2735 2736 /* When ramping down, set clock dividers last. */ 2737 if (freq < old_freq) { 2738 HWRITE4(sc, clksel, 2739 RK3399_CRU_CLK_CORE_DIV_CON_MASK << 16 | 2740 0 << RK3399_CRU_CLK_CORE_DIV_CON_SHIFT | 2741 RK3399_CRU_ACLKM_CORE_DIV_CON_MASK << 16 | 2742 1 << RK3399_CRU_ACLKM_CORE_DIV_CON_SHIFT); 2743 HWRITE4(sc, clksel + 0x0004, 2744 RK3399_CRU_PCLK_DBG_DIV_CON_MASK << 16 | 2745 div << RK3399_CRU_PCLK_DBG_DIV_CON_SHIFT | 2746 RK3399_CRU_ATCLK_CORE_DIV_CON_MASK << 16 | 2747 div << RK3399_CRU_ATCLK_CORE_DIV_CON_SHIFT); 2748 } 2749 2750 return 0; 2751 } 2752 2753 uint32_t 2754 rk3399_get_frac(struct rkclock_softc *sc, uint32_t parent, bus_size_t base) 2755 { 2756 uint32_t parent_freq, frac; 2757 uint16_t n, d; 2758 2759 frac = HREAD4(sc, base); 2760 n = frac >> 16; 2761 d = frac & 0xffff; 2762 if (n == 0 || d == 0) 2763 n = d = 1; 2764 parent_freq = sc->sc_cd.cd_get_frequency(sc, &parent); 2765 return ((uint64_t)parent_freq * n) / d; 2766 } 2767 2768 int 2769 rk3399_set_frac(struct rkclock_softc *sc, uint32_t parent, bus_size_t base, 2770 uint32_t freq) 2771 { 2772 uint32_t n, d; 2773 uint32_t p0, p1, p2; 2774 uint32_t q0, q1, q2; 2775 uint32_t a, tmp; 2776 2777 n = freq; 2778 d = sc->sc_cd.cd_get_frequency(sc, &parent); 2779 2780 /* 2781 * The denominator needs to be at least 20 times the numerator 2782 * for a stable clock. 2783 */ 2784 if (n == 0 || d == 0 || d < 20 * n) 2785 return -1; 2786 2787 /* 2788 * This is a simplified implementation of the algorithm to 2789 * calculate the best rational approximation using continued 2790 * fractions. 2791 */ 2792 2793 p0 = q1 = 0; 2794 p1 = q0 = 1; 2795 2796 while (d != 0) { 2797 /* 2798 * Calculate next coefficient in the continued 2799 * fraction and keep track of the remainder. 2800 */ 2801 tmp = d; 2802 a = n / d; 2803 d = n % d; 2804 n = tmp; 2805 2806 /* 2807 * Calculate next approximation in the series based on 2808 * the current coefficient. 2809 */ 2810 p2 = p0 + a * p1; 2811 q2 = q0 + a * q1; 2812 2813 /* 2814 * Terminate if we reached the maximum allowed 2815 * denominator. 2816 */ 2817 if (q2 > 0xffff) 2818 break; 2819 2820 p0 = p1; p1 = p2; 2821 q0 = q1; q1 = q2; 2822 } 2823 2824 HWRITE4(sc, base, p1 << 16 | q1); 2825 return 0; 2826 } 2827 2828 uint32_t 2829 rk3399_get_frequency(void *cookie, uint32_t *cells) 2830 { 2831 struct rkclock_softc *sc = cookie; 2832 uint32_t idx = cells[0]; 2833 2834 switch (idx) { 2835 case RK3399_PLL_ALPLL: 2836 return rk3399_get_pll(sc, RK3399_CRU_LPLL_CON(0)); 2837 case RK3399_PLL_ABPLL: 2838 return rk3399_get_pll(sc, RK3399_CRU_BPLL_CON(0)); 2839 case RK3399_PLL_DPLL: 2840 return rk3399_get_pll(sc, RK3399_CRU_DPLL_CON(0)); 2841 case RK3399_PLL_CPLL: 2842 return rk3399_get_pll(sc, RK3399_CRU_CPLL_CON(0)); 2843 case RK3399_PLL_GPLL: 2844 return rk3399_get_pll(sc, RK3399_CRU_GPLL_CON(0)); 2845 case RK3399_PLL_NPLL: 2846 return rk3399_get_pll(sc, RK3399_CRU_NPLL_CON(0)); 2847 case RK3399_PLL_VPLL: 2848 return rk3399_get_pll(sc, RK3399_CRU_VPLL_CON(0)); 2849 case RK3399_ARMCLKL: 2850 return rk3399_get_armclk(sc, RK3399_CRU_CLKSEL_CON(0)); 2851 case RK3399_ARMCLKB: 2852 return rk3399_get_armclk(sc, RK3399_CRU_CLKSEL_CON(2)); 2853 case RK3399_XIN24M: 2854 return 24000000; 2855 case RK3399_CLK_32K: 2856 return 32768; 2857 case RK3399_XIN12M: 2858 return 12000000; 2859 case RK3399_CLK_I2S0_FRAC: 2860 return rk3399_get_frac(sc, RK3399_CLK_I2S0_DIV, 2861 RK3399_CRU_CLKSEL_CON(96)); 2862 case RK3399_CLK_I2S1_FRAC: 2863 return rk3399_get_frac(sc, RK3399_CLK_I2S1_DIV, 2864 RK3399_CRU_CLKSEL_CON(97)); 2865 case RK3399_CLK_I2S2_FRAC: 2866 return rk3399_get_frac(sc, RK3399_CLK_I2S2_DIV, 2867 RK3399_CRU_CLKSEL_CON(98)); 2868 default: 2869 break; 2870 } 2871 2872 return rkclock_get_frequency(sc, idx); 2873 } 2874 2875 int 2876 rk3399_set_frequency(void *cookie, uint32_t *cells, uint32_t freq) 2877 { 2878 struct rkclock_softc *sc = cookie; 2879 uint32_t idx = cells[0]; 2880 2881 switch (idx) { 2882 case RK3399_PLL_ALPLL: 2883 return rk3399_set_pll(sc, RK3399_CRU_LPLL_CON(0), freq); 2884 case RK3399_PLL_ABPLL: 2885 return rk3399_set_pll(sc, RK3399_CRU_BPLL_CON(0), freq); 2886 case RK3399_PLL_CPLL: 2887 return rk3399_set_pll(sc, RK3399_CRU_CPLL_CON(0), freq); 2888 case RK3399_PLL_GPLL: 2889 return rk3399_set_pll(sc, RK3399_CRU_GPLL_CON(0), freq); 2890 case RK3399_PLL_NPLL: 2891 return rk3399_set_pll(sc, RK3399_CRU_NPLL_CON(0), freq); 2892 case RK3399_PLL_VPLL: 2893 return rk3399_set_pll(sc, RK3399_CRU_VPLL_CON(0), freq); 2894 case RK3399_ARMCLKL: 2895 return rk3399_set_armclk(sc, RK3399_CRU_CLKSEL_CON(0), freq); 2896 case RK3399_ARMCLKB: 2897 return rk3399_set_armclk(sc, RK3399_CRU_CLKSEL_CON(2), freq); 2898 case RK3399_CLK_I2S0_8CH: 2899 rkclock_set_parent(sc, idx, RK3399_CLK_I2S0_FRAC); 2900 return rkclock_set_frequency(sc, idx, freq); 2901 case RK3399_CLK_I2S1_8CH: 2902 rkclock_set_parent(sc, idx, RK3399_CLK_I2S1_FRAC); 2903 return rkclock_set_frequency(sc, idx, freq); 2904 case RK3399_CLK_I2S2_8CH: 2905 rkclock_set_parent(sc, idx, RK3399_CLK_I2S2_FRAC); 2906 return rkclock_set_frequency(sc, idx, freq); 2907 case RK3399_XIN12M: 2908 if (freq / (1000 * 1000) != 12) 2909 return -1; 2910 return 0; 2911 case RK3399_CLK_I2S0_FRAC: 2912 return rk3399_set_frac(sc, RK3399_CLK_I2S0_DIV, 2913 RK3399_CRU_CLKSEL_CON(96), freq); 2914 case RK3399_CLK_I2S1_FRAC: 2915 return rk3399_set_frac(sc, RK3399_CLK_I2S1_DIV, 2916 RK3399_CRU_CLKSEL_CON(97), freq); 2917 case RK3399_CLK_I2S2_FRAC: 2918 return rk3399_set_frac(sc, RK3399_CLK_I2S2_DIV, 2919 RK3399_CRU_CLKSEL_CON(98), freq); 2920 default: 2921 break; 2922 } 2923 2924 return rkclock_set_frequency(sc, idx, freq); 2925 } 2926 2927 2928 int 2929 rk3399_set_parent(void *cookie, uint32_t *cells, uint32_t *pcells) 2930 { 2931 struct rkclock_softc *sc = cookie; 2932 2933 if (pcells[0] != sc->sc_phandle) 2934 return -1; 2935 2936 return rkclock_set_parent(sc, cells[0], pcells[1]); 2937 } 2938 2939 void 2940 rk3399_enable(void *cookie, uint32_t *cells, int on) 2941 { 2942 struct rkclock_softc *sc = cookie; 2943 uint32_t idx = cells[0]; 2944 2945 /* 2946 * All clocks are enabled upon hardware reset, but on some boards the 2947 * firmware will disable some of them. Handle those here. 2948 */ 2949 if (!on) { 2950 printf("%s: 0x%08x\n", __func__, idx); 2951 return; 2952 } 2953 2954 switch (idx) { 2955 case RK3399_ACLK_GMAC: 2956 HWRITE4(sc, RK3399_CRU_CLKGATE_CON(32), (1 << 0) << 16); 2957 break; 2958 case RK3399_PCLK_GMAC: 2959 HWRITE4(sc, RK3399_CRU_CLKGATE_CON(32), (1 << 2) << 16); 2960 break; 2961 case RK3399_CLK_MAC: 2962 HWRITE4(sc, RK3399_CRU_CLKGATE_CON(5), (1 << 5) << 16); 2963 break; 2964 case RK3399_CLK_MAC_RX: 2965 HWRITE4(sc, RK3399_CRU_CLKGATE_CON(5), (1 << 8) << 16); 2966 break; 2967 case RK3399_CLK_MAC_TX: 2968 HWRITE4(sc, RK3399_CRU_CLKGATE_CON(5), (1 << 9) << 16); 2969 break; 2970 } 2971 } 2972 2973 void 2974 rk3399_reset(void *cookie, uint32_t *cells, int on) 2975 { 2976 struct rkclock_softc *sc = cookie; 2977 uint32_t idx = cells[0]; 2978 uint32_t mask = (1 << (idx % 16)); 2979 2980 HWRITE4(sc, RK3399_CRU_SOFTRST_CON(idx / 16), 2981 mask << 16 | (on ? mask : 0)); 2982 } 2983 2984 /* PMUCRU */ 2985 2986 const struct rkclock rk3399_pmu_clocks[] = { 2987 { 2988 RK3399_CLK_I2C0, RK3399_PMUCRU_CLKSEL_CON(2), 2989 0, DIV(6, 0), 2990 { RK3399_PLL_PPLL } 2991 }, 2992 { 2993 RK3399_CLK_I2C4, RK3399_PMUCRU_CLKSEL_CON(3), 2994 0, DIV(6, 0), 2995 { RK3399_PLL_PPLL } 2996 }, 2997 { 2998 RK3399_CLK_I2C8, RK3399_PMUCRU_CLKSEL_CON(2), 2999 0, DIV(14, 8), 3000 { RK3399_PLL_PPLL } 3001 }, 3002 { 3003 RK3399_PCLK_RKPWM, RK3399_PMUCRU_CLKSEL_CON(0), 3004 0, DIV(6, 0), 3005 { RK3399_PLL_PPLL } 3006 }, 3007 { 3008 /* Sentinel */ 3009 } 3010 }; 3011 3012 void 3013 rk3399_pmu_init(struct rkclock_softc *sc) 3014 { 3015 sc->sc_clocks = rk3399_pmu_clocks; 3016 rk3399_pmucru_sc = sc; 3017 } 3018 3019 uint32_t 3020 rk3399_pmu_get_frequency(void *cookie, uint32_t *cells) 3021 { 3022 struct rkclock_softc *sc = cookie; 3023 uint32_t idx = cells[0]; 3024 3025 switch (idx) { 3026 case RK3399_PLL_PPLL: 3027 return rk3399_get_pll(sc, RK3399_PMUCRU_PPLL_CON(0)); 3028 default: 3029 break; 3030 } 3031 3032 return rkclock_get_frequency(sc, idx); 3033 } 3034 3035 int 3036 rk3399_pmu_set_frequency(void *cookie, uint32_t *cells, uint32_t freq) 3037 { 3038 struct rkclock_softc *sc = cookie; 3039 uint32_t idx = cells[0]; 3040 3041 switch (idx) { 3042 case RK3399_PLL_PPLL: 3043 return rk3399_set_pll(sc, RK3399_PMUCRU_PPLL_CON(0), freq); 3044 default: 3045 break; 3046 } 3047 3048 return rkclock_set_frequency(sc, idx, freq); 3049 } 3050 3051 void 3052 rk3399_pmu_enable(void *cookie, uint32_t *cells, int on) 3053 { 3054 uint32_t idx = cells[0]; 3055 3056 switch (idx) { 3057 case RK3399_CLK_I2C0: 3058 case RK3399_CLK_I2C4: 3059 case RK3399_CLK_I2C8: 3060 case RK3399_PCLK_I2C0: 3061 case RK3399_PCLK_I2C4: 3062 case RK3399_PCLK_I2C8: 3063 case RK3399_PCLK_RKPWM: 3064 /* Enabled by default. */ 3065 break; 3066 default: 3067 printf("%s: 0x%08x\n", __func__, idx); 3068 break; 3069 } 3070 } 3071 3072 void 3073 rk3399_pmu_reset(void *cookie, uint32_t *cells, int on) 3074 { 3075 uint32_t idx = cells[0]; 3076 3077 printf("%s: 0x%08x\n", __func__, idx); 3078 } 3079 3080 /* 3081 * Rockchip RK3568 3082 */ 3083 3084 const struct rkclock rk3568_clocks[] = { 3085 { 3086 RK3568_BCLK_EMMC, RK3568_CRU_CLKSEL_CON(28), 3087 SEL(9, 8), 0, 3088 { RK3568_GPLL_200M, RK3568_GPLL_150M, RK3568_CPLL_125M } 3089 }, 3090 { 3091 RK3568_CCLK_EMMC, RK3568_CRU_CLKSEL_CON(28), 3092 SEL(14, 12), 0, 3093 { RK3568_XIN24M, RK3568_GPLL_200M, RK3568_GPLL_150M, 3094 RK3568_CPLL_100M, RK3568_CPLL_50M, RK3568_CLK_OSC0_DIV_375K } 3095 }, 3096 { 3097 RK3568_TCLK_EMMC, 0, 0, 0, 3098 { RK3568_XIN24M } 3099 }, 3100 3101 { 3102 RK3568_ACLK_PHP, RK3568_CRU_CLKSEL_CON(30), 3103 SEL(1, 0), 0, 3104 { RK3568_GPLL_300M, RK3568_GPLL_200M, 3105 RK3568_GPLL_100M, RK3568_XIN24M } 3106 }, 3107 { 3108 RK3568_PCLK_PHP, RK3568_CRU_CLKSEL_CON(30), 3109 0, DIV(7, 4), 3110 { RK3568_ACLK_PHP } 3111 }, 3112 { 3113 RK3568_CLK_SDMMC0, RK3568_CRU_CLKSEL_CON(30), 3114 SEL(10, 8), 0, 3115 { RK3568_XIN24M, RK3568_GPLL_400M, RK3568_GPLL_300M, 3116 RK3568_CPLL_100M, RK3568_CPLL_50M, RK3568_CLK_OSC0_DIV_750K } 3117 }, 3118 { 3119 RK3568_CLK_SDMMC1, RK3568_CRU_CLKSEL_CON(30), 3120 SEL(14, 12), 0, 3121 { RK3568_XIN24M, RK3568_GPLL_400M, RK3568_GPLL_300M, 3122 RK3568_CPLL_100M, RK3568_CPLL_50M, RK3568_CLK_OSC0_DIV_750K } 3123 }, 3124 { 3125 RK3568_CLK_SDMMC2, RK3568_CRU_CLKSEL_CON(32), 3126 SEL(10, 8), 0, 3127 { RK3568_XIN24M, RK3568_GPLL_400M, RK3568_GPLL_300M, 3128 RK3568_CPLL_100M, RK3568_CPLL_50M, RK3568_CLK_OSC0_DIV_750K } 3129 }, 3130 { 3131 RK3568_ACLK_GMAC0, 0, 0, 0, 3132 { RK3568_ACLK_PHP } 3133 }, 3134 { 3135 RK3568_PCLK_GMAC0, 0, 0, 0, 3136 { RK3568_PCLK_PHP } 3137 }, 3138 { 3139 RK3568_CLK_MAC0_2TOP, RK3568_CRU_CLKSEL_CON(31), 3140 SEL(9, 8), 0, 3141 { RK3568_CPLL_125M, RK3568_CPLL_50M, 3142 RK3568_CPLL_25M, RK3568_XIN24M } 3143 }, 3144 { 3145 RK3568_CLK_MAC0_REFOUT, 0, 0, 0, 3146 { RK3568_CLK_MAC0_2TOP } 3147 }, 3148 { 3149 RK3568_CLK_GMAC0_PTP_REF, RK3568_CRU_CLKSEL_CON(31), 3150 SEL(13, 12), 0, 3151 { RK3568_CPLL_62P5M, RK3568_GPLL_100M, 3152 RK3568_CPLL_50M, RK3568_XIN24M } 3153 }, 3154 { 3155 RK3568_ACLK_USB, RK3568_CRU_CLKSEL_CON(32), 3156 SEL(1, 0), 0, 3157 { RK3568_GPLL_300M, RK3568_GPLL_200M, 3158 RK3568_GPLL_100M, RK3568_XIN24M } 3159 }, 3160 { 3161 RK3568_PCLK_USB, RK3568_CRU_CLKSEL_CON(32), 3162 0, DIV(7, 4), 3163 { RK3568_ACLK_USB } 3164 }, 3165 { 3166 RK3568_ACLK_GMAC1, 0, 0, 0, 3167 { RK3568_ACLK_USB } 3168 }, 3169 { 3170 RK3568_PCLK_GMAC1, 0, 0, 0, 3171 { RK3568_PCLK_USB } 3172 }, 3173 { 3174 RK3568_CLK_MAC1_2TOP, RK3568_CRU_CLKSEL_CON(33), 3175 SEL(9, 8), 0, 3176 { RK3568_CPLL_125M, RK3568_CPLL_50M, 3177 RK3568_CPLL_25M, RK3568_XIN24M } 3178 }, 3179 { 3180 RK3568_CLK_MAC1_REFOUT, 0, 0, 0, 3181 { RK3568_CLK_MAC1_2TOP } 3182 }, 3183 { 3184 RK3568_CLK_GMAC1_PTP_REF, RK3568_CRU_CLKSEL_CON(33), 3185 SEL(13, 12), 0, 3186 { RK3568_CPLL_62P5M, RK3568_GPLL_100M, 3187 RK3568_CPLL_50M, RK3568_XIN24M } 3188 }, 3189 { 3190 RK3568_CLK_TSADC_TSEN, RK3568_CRU_CLKSEL_CON(51), 3191 SEL(5, 4), DIV(2, 0), 3192 { RK3568_XIN24M, RK3568_GPLL_100M, RK3568_CPLL_100M } 3193 }, 3194 { 3195 RK3568_CLK_TSADC, RK3568_CRU_CLKSEL_CON(51), 3196 0, DIV(14, 8), 3197 { RK3568_CLK_TSADC_TSEN } 3198 }, 3199 { 3200 RK3568_SCLK_UART1, RK3568_CRU_CLKSEL_CON(52), 3201 SEL(13, 12), 0, 3202 { 0, 0, RK3568_XIN24M } 3203 }, 3204 { 3205 RK3568_SCLK_UART2, RK3568_CRU_CLKSEL_CON(54), 3206 SEL(13, 12), 0, 3207 { 0, 0, RK3568_XIN24M } 3208 }, 3209 { 3210 RK3568_SCLK_UART3, RK3568_CRU_CLKSEL_CON(56), 3211 SEL(13, 12), 0, 3212 { 0, 0, RK3568_XIN24M } 3213 }, 3214 { 3215 RK3568_SCLK_UART4, RK3568_CRU_CLKSEL_CON(58), 3216 SEL(13, 12), 0, 3217 { 0, 0, RK3568_XIN24M } 3218 }, 3219 { 3220 RK3568_SCLK_UART5, RK3568_CRU_CLKSEL_CON(60), 3221 SEL(13, 12), 0, 3222 { 0, 0, RK3568_XIN24M } 3223 }, 3224 { 3225 RK3568_SCLK_UART6, RK3568_CRU_CLKSEL_CON(62), 3226 SEL(13, 12), 0, 3227 { 0, 0, RK3568_XIN24M } 3228 }, 3229 { 3230 RK3568_SCLK_UART7, RK3568_CRU_CLKSEL_CON(64), 3231 SEL(13, 12), 0, 3232 { 0, 0, RK3568_XIN24M } 3233 }, 3234 { 3235 RK3568_SCLK_UART8, RK3568_CRU_CLKSEL_CON(66), 3236 SEL(13, 12), 0, 3237 { 0, 0, RK3568_XIN24M } 3238 }, 3239 { 3240 RK3568_SCLK_UART9, RK3568_CRU_CLKSEL_CON(68), 3241 SEL(13, 12), 0, 3242 { 0, 0, RK3568_XIN24M } 3243 }, 3244 { 3245 RK3568_CLK_I2C, RK3568_CRU_CLKSEL_CON(71), 3246 SEL(9, 8), 0, 3247 { 0, 0, RK3568_XIN24M } 3248 }, 3249 { 3250 RK3568_CLK_I2C1, 0, 0, 0, 3251 { RK3568_CLK_I2C } 3252 }, 3253 { 3254 RK3568_CLK_I2C2, 0, 0, 0, 3255 { RK3568_CLK_I2C } 3256 }, 3257 { 3258 RK3568_CLK_I2C3, 0, 0, 0, 3259 { RK3568_CLK_I2C } 3260 }, 3261 { 3262 RK3568_CLK_I2C4, 0, 0, 0, 3263 { RK3568_CLK_I2C } 3264 }, 3265 { 3266 RK3568_CLK_I2C5, 0, 0, 0, 3267 { RK3568_CLK_I2C } 3268 }, 3269 { 3270 RK3568_SCLK_GMAC0, RK3568_CRU_CLKSEL_CON(31), 3271 SEL(2, 2), 0, 3272 { RK3568_CLK_MAC0_2TOP, RK3568_GMAC0_CLKIN } 3273 }, 3274 { 3275 RK3568_SCLK_GMAC0_RGMII_SPEED, RK3568_CRU_CLKSEL_CON(31), 3276 SEL(5, 4), 0, 3277 { RK3568_SCLK_GMAC0, RK3568_SCLK_GMAC0, 3278 RK3568_SCLK_GMAC0_DIV_50, RK3568_SCLK_GMAC0_DIV_5 } 3279 }, 3280 { 3281 RK3568_SCLK_GMAC0_RMII_SPEED, RK3568_CRU_CLKSEL_CON(31), 3282 SEL(3, 3), 0, 3283 { RK3568_SCLK_GMAC0_DIV_20, RK3568_SCLK_GMAC0_DIV_2 } 3284 }, 3285 { 3286 RK3568_SCLK_GMAC0_RX_TX, RK3568_CRU_CLKSEL_CON(31), 3287 SEL(1, 0), 0, 3288 { RK3568_SCLK_GMAC0_RGMII_SPEED, RK3568_SCLK_GMAC0_RMII_SPEED } 3289 }, 3290 { 3291 RK3568_SCLK_GMAC1, RK3568_CRU_CLKSEL_CON(33), 3292 SEL(2, 2), 0, 3293 { RK3568_CLK_MAC1_2TOP, RK3568_GMAC1_CLKIN } 3294 }, 3295 { 3296 RK3568_SCLK_GMAC1_RGMII_SPEED, RK3568_CRU_CLKSEL_CON(33), 3297 SEL(5, 4), 0, 3298 { RK3568_SCLK_GMAC1, RK3568_SCLK_GMAC1, 3299 RK3568_SCLK_GMAC1_DIV_50, RK3568_SCLK_GMAC1_DIV_5 } 3300 }, 3301 { 3302 RK3568_SCLK_GMAC1_RMII_SPEED, RK3568_CRU_CLKSEL_CON(33), 3303 SEL(3, 3), 0, 3304 { RK3568_SCLK_GMAC1_DIV_20, RK3568_SCLK_GMAC1_DIV_2 } 3305 }, 3306 { 3307 RK3568_SCLK_GMAC1_RX_TX, RK3568_CRU_CLKSEL_CON(33), 3308 SEL(1, 0), 0, 3309 { RK3568_SCLK_GMAC1_RGMII_SPEED, RK3568_SCLK_GMAC1_RMII_SPEED } 3310 }, 3311 { 3312 RK3568_CPLL_125M, RK3568_CRU_CLKSEL_CON(80), 3313 0, DIV(4, 0), 3314 { RK3568_PLL_CPLL } 3315 }, 3316 { 3317 RK3568_CPLL_62P5M, RK3568_CRU_CLKSEL_CON(80), 3318 0, DIV(12, 8), 3319 { RK3568_PLL_CPLL } 3320 }, 3321 { 3322 RK3568_CPLL_50M, RK3568_CRU_CLKSEL_CON(81), 3323 0, DIV(4, 0), 3324 { RK3568_PLL_CPLL } 3325 }, 3326 { 3327 RK3568_CPLL_25M, RK3568_CRU_CLKSEL_CON(81), 3328 0, DIV(13, 8), 3329 { RK3568_PLL_CPLL } 3330 }, 3331 { 3332 RK3568_CPLL_100M, RK3568_CRU_CLKSEL_CON(82), 3333 0, DIV(4, 0), 3334 { RK3568_PLL_CPLL } 3335 }, 3336 { 3337 RK3568_GPLL_400M, RK3568_CRU_CLKSEL_CON(75), 3338 0, DIV(4, 0), 3339 { RK3568_PLL_GPLL } 3340 }, 3341 { 3342 RK3568_GPLL_300M, RK3568_CRU_CLKSEL_CON(75), 3343 0, DIV(12, 8), 3344 { RK3568_PLL_GPLL } 3345 }, 3346 { 3347 RK3568_GPLL_200M, RK3568_CRU_CLKSEL_CON(76), 3348 0, DIV(4, 0), 3349 { RK3568_PLL_GPLL } 3350 }, 3351 { 3352 RK3568_GPLL_150M, RK3568_CRU_CLKSEL_CON(76), 3353 0, DIV(12, 5), 3354 { RK3568_PLL_GPLL } 3355 }, 3356 { 3357 RK3568_GPLL_100M, RK3568_CRU_CLKSEL_CON(77), 3358 0, DIV(4, 0), 3359 { RK3568_PLL_GPLL } 3360 }, 3361 { 3362 RK3568_CLK_OSC0_DIV_750K, RK3568_CRU_CLKSEL_CON(82), 3363 0, DIV(13, 8), 3364 { RK3568_XIN24M } 3365 }, 3366 { 3367 /* Sentinel */ 3368 } 3369 }; 3370 3371 void 3372 rk3568_init(struct rkclock_softc *sc) 3373 { 3374 int i; 3375 3376 /* The code below assumes all clocks are enabled. Check this!. */ 3377 for (i = 0; i <= 35; i++) { 3378 if (HREAD4(sc, RK3568_CRU_GATE_CON(i)) != 0x00000000) { 3379 printf("CRU_GATE_CON%d: 0x%08x\n", i, 3380 HREAD4(sc, RK3568_CRU_GATE_CON(i))); 3381 } 3382 } 3383 3384 sc->sc_clocks = rk3568_clocks; 3385 } 3386 3387 int 3388 rk3568_set_pll(struct rkclock_softc *sc, bus_size_t base, uint32_t freq) 3389 { 3390 uint32_t fbdiv, postdiv1, postdiv2, refdiv; 3391 int mode_shift = -1; 3392 3393 switch (base) { 3394 case RK3568_CRU_APLL_CON(0): 3395 mode_shift = 0; 3396 break; 3397 case RK3568_CRU_DPLL_CON(0): 3398 mode_shift = 2; 3399 break; 3400 case RK3568_CRU_CPLL_CON(0): 3401 mode_shift = 4; 3402 break; 3403 case RK3568_CRU_GPLL_CON(0): 3404 mode_shift = 6; 3405 break; 3406 case RK3568_CRU_NPLL_CON(0): 3407 mode_shift = 10; 3408 break; 3409 case RK3568_CRU_VPLL_CON(0): 3410 mode_shift = 12; 3411 break; 3412 } 3413 KASSERT(mode_shift != -1); 3414 3415 /* 3416 * It is not clear whether all combinations of the clock 3417 * dividers result in a stable clock. Therefore this function 3418 * only supports a limited set of PLL clock rates. 3419 */ 3420 switch (freq) { 3421 case 1200000000U: 3422 postdiv1 = 2; postdiv2 = refdiv = 1; 3423 break; 3424 default: 3425 printf("%s: %u Hz\n", __func__, freq); 3426 return -1; 3427 } 3428 3429 /* Calculate feedback divider. */ 3430 fbdiv = freq * postdiv1 * postdiv2 * refdiv / 24000000; 3431 3432 /* 3433 * Select slow mode to guarantee a stable clock while we're 3434 * adjusting the PLL. 3435 */ 3436 HWRITE4(sc, RK3568_CRU_MODE_CON, 3437 (RK3328_CRU_CRU_MODE_MASK << 16 | 3438 RK3328_CRU_CRU_MODE_SLOW) << mode_shift); 3439 3440 /* Set PLL rate. */ 3441 HWRITE4(sc, base + 0x0000, 3442 RK3328_CRU_PLL_POSTDIV1_MASK << 16 | 3443 postdiv1 << RK3328_CRU_PLL_POSTDIV1_SHIFT | 3444 RK3328_CRU_PLL_FBDIV_MASK << 16 | 3445 fbdiv << RK3328_CRU_PLL_FBDIV_SHIFT); 3446 HWRITE4(sc, base + 0x0004, 3447 RK3328_CRU_PLL_DSMPD << 16 | RK3328_CRU_PLL_DSMPD | 3448 RK3328_CRU_PLL_POSTDIV2_MASK << 16 | 3449 postdiv2 << RK3328_CRU_PLL_POSTDIV2_SHIFT | 3450 RK3328_CRU_PLL_REFDIV_MASK << 16 | 3451 refdiv << RK3328_CRU_PLL_REFDIV_SHIFT); 3452 3453 /* Wait for PLL to stabilize. */ 3454 while ((HREAD4(sc, base + 0x0004) & RK3328_CRU_PLL_PLL_LOCK) == 0) 3455 delay(10); 3456 3457 /* Switch back to normal mode. */ 3458 HWRITE4(sc, RK3568_CRU_MODE_CON, 3459 (RK3328_CRU_CRU_MODE_MASK << 16 | 3460 RK3328_CRU_CRU_MODE_NORMAL) << mode_shift); 3461 3462 return 0; 3463 } 3464 3465 uint32_t 3466 rk3568_get_frequency(void *cookie, uint32_t *cells) 3467 { 3468 struct rkclock_softc *sc = cookie; 3469 uint32_t idx = cells[0]; 3470 3471 switch (idx) { 3472 case RK3568_PLL_APLL: 3473 return rk3328_get_pll(sc, RK3568_CRU_APLL_CON(0)); 3474 case RK3568_PLL_DPLL: 3475 return rk3328_get_pll(sc, RK3568_CRU_DPLL_CON(0)); 3476 case RK3568_PLL_CPLL: 3477 return rk3328_get_pll(sc, RK3568_CRU_CPLL_CON(0)); 3478 case RK3568_PLL_GPLL: 3479 return rk3328_get_pll(sc, RK3568_CRU_GPLL_CON(0)); 3480 case RK3568_PLL_NPLL: 3481 return rk3328_get_pll(sc, RK3568_CRU_NPLL_CON(0)); 3482 case RK3568_PLL_VPLL: 3483 return rk3328_get_pll(sc, RK3568_CRU_VPLL_CON(0)); 3484 case RK3568_SCLK_GMAC0_DIV_50: 3485 idx = RK3568_SCLK_GMAC0; 3486 return rk3568_get_frequency(sc, &idx) / 50; 3487 case RK3568_SCLK_GMAC0_DIV_5: 3488 idx = RK3568_SCLK_GMAC0; 3489 return rk3568_get_frequency(sc, &idx) / 5; 3490 case RK3568_SCLK_GMAC0_DIV_20: 3491 idx = RK3568_SCLK_GMAC0; 3492 return rk3568_get_frequency(sc, &idx) / 20; 3493 case RK3568_SCLK_GMAC0_DIV_2: 3494 idx = RK3568_SCLK_GMAC0; 3495 return rk3568_get_frequency(sc, &idx) / 2; 3496 case RK3568_SCLK_GMAC1_DIV_50: 3497 idx = RK3568_SCLK_GMAC1; 3498 return rk3568_get_frequency(sc, &idx) / 50; 3499 case RK3568_SCLK_GMAC1_DIV_5: 3500 idx = RK3568_SCLK_GMAC1; 3501 return rk3568_get_frequency(sc, &idx) / 5; 3502 case RK3568_SCLK_GMAC1_DIV_20: 3503 idx = RK3568_SCLK_GMAC1; 3504 return rk3568_get_frequency(sc, &idx) / 20; 3505 case RK3568_SCLK_GMAC1_DIV_2: 3506 idx = RK3568_SCLK_GMAC1; 3507 return rk3568_get_frequency(sc, &idx) / 2; 3508 case RK3568_CLK_OSC0_DIV_375K: 3509 idx = RK3568_CLK_OSC0_DIV_750K; 3510 return rk3568_get_frequency(sc, &idx) / 2; 3511 case RK3568_GMAC0_CLKIN: 3512 return rkclock_external_frequency("gmac0_clkin"); 3513 case RK3568_GMAC1_CLKIN: 3514 return rkclock_external_frequency("gmac1_clkin"); 3515 case RK3568_XIN24M: 3516 return 24000000; 3517 default: 3518 break; 3519 } 3520 3521 return rkclock_get_frequency(sc, idx); 3522 } 3523 3524 int 3525 rk3568_set_frequency(void *cookie, uint32_t *cells, uint32_t freq) 3526 { 3527 struct rkclock_softc *sc = cookie; 3528 uint32_t idx = cells[0]; 3529 3530 switch (idx) { 3531 case RK3568_PLL_GPLL: 3532 return rk3568_set_pll(sc, RK3568_CRU_GPLL_CON(0), freq); 3533 default: 3534 break; 3535 } 3536 3537 return rkclock_set_frequency(sc, idx, freq); 3538 } 3539 3540 int 3541 rk3568_set_parent(void *cookie, uint32_t *cells, uint32_t *pcells) 3542 { 3543 struct rkclock_softc *sc = cookie; 3544 char buf[64] = {}; 3545 int len, node; 3546 3547 if (pcells[0] != sc->sc_phandle) { 3548 node = OF_getnodebyphandle(pcells[0]); 3549 if (node == 0) 3550 return -1; 3551 len = OF_getproplen(node, "clock-output-names"); 3552 if (len <= 0 || len > sizeof(buf)) 3553 return -1; 3554 OF_getprop(node, "clock-output-names", buf, sizeof(buf)); 3555 3556 if (strcmp(buf, "gmac0_clkin") == 0) { 3557 return rkclock_set_parent(sc, cells[0], 3558 RK3568_GMAC0_CLKIN); 3559 } 3560 if (strcmp(buf, "gmac1_clkin") == 0) { 3561 return rkclock_set_parent(sc, cells[0], 3562 RK3568_GMAC1_CLKIN); 3563 } 3564 3565 printf("%s: 0x%08x 0x%08x\n", __func__, cells[0], pcells[0]); 3566 return -1; 3567 } 3568 3569 return rkclock_set_parent(sc, cells[0], pcells[1]); 3570 } 3571 3572 void 3573 rk3568_enable(void *cookie, uint32_t *cells, int on) 3574 { 3575 uint32_t idx = cells[0]; 3576 3577 /* All clocks are enabled upon hardware reset. */ 3578 if (!on) { 3579 printf("%s: 0x%08x\n", __func__, idx); 3580 return; 3581 } 3582 } 3583 3584 void 3585 rk3568_reset(void *cookie, uint32_t *cells, int on) 3586 { 3587 struct rkclock_softc *sc = cookie; 3588 uint32_t idx = cells[0]; 3589 uint32_t mask = (1 << (idx % 16)); 3590 3591 HWRITE4(sc, RK3568_CRU_SOFTRST_CON(idx / 16), 3592 mask << 16 | (on ? mask : 0)); 3593 } 3594 3595 /* PMUCRU */ 3596 3597 const struct rkclock rk3568_pmu_clocks[] = { 3598 { 3599 RK3568_CLK_RTC_32K, RK3568_PMUCRU_CLKSEL_CON(0), 3600 SEL(7, 6), 0, 3601 { 0, RK3568_XIN32K, RK3568_CLK_RTC32K_FRAC }, 3602 SET_PARENT 3603 }, 3604 { 3605 RK3568_CLK_I2C0, RK3568_PMUCRU_CLKSEL_CON(3), 3606 0, DIV(15, 7), 3607 { RK3568_CLK_PDPMU } 3608 }, 3609 { 3610 RK3568_SCLK_UART0, RK3568_PMUCRU_CLKSEL_CON(4), 3611 SEL(11, 10), 0, 3612 { 0, 0, RK3568_XIN24M } 3613 }, 3614 { 3615 RK3568_CLK_PCIEPHY0_OSC0, 0, 0, 0, 3616 { RK3568_XIN24M } 3617 }, 3618 { 3619 RK3568_CLK_PCIEPHY0_DIV, RK3568_PMUCRU_CLKSEL_CON(9), 3620 0, DIV(2, 0), 3621 { RK3568_PPLL_PH0 } 3622 }, 3623 { 3624 RK3568_CLK_PCIEPHY0_REF, RK3568_PMUCRU_CLKSEL_CON(9), 3625 SEL(3, 3), 0, 3626 { RK3568_CLK_PCIEPHY0_OSC0, RK3568_CLK_PCIEPHY0_DIV }, 3627 SET_PARENT 3628 }, 3629 { 3630 RK3568_CLK_PCIEPHY1_OSC0, 0, 0, 0, 3631 { RK3568_XIN24M } 3632 }, 3633 { 3634 RK3568_CLK_PCIEPHY1_DIV, RK3568_PMUCRU_CLKSEL_CON(9), 3635 0, DIV(6, 4), 3636 { RK3568_PPLL_PH0 } 3637 }, 3638 { 3639 RK3568_CLK_PCIEPHY1_REF, RK3568_PMUCRU_CLKSEL_CON(9), 3640 SEL(7, 7), 0, 3641 { RK3568_CLK_PCIEPHY1_OSC0, RK3568_CLK_PCIEPHY1_DIV }, 3642 SET_PARENT 3643 }, 3644 { 3645 RK3568_CLK_PCIEPHY2_OSC0, 0, 0, 0, 3646 { RK3568_XIN24M } 3647 }, 3648 { 3649 RK3568_CLK_PCIEPHY2_DIV, RK3568_PMUCRU_CLKSEL_CON(9), 3650 0, DIV(10, 8), 3651 { RK3568_PPLL_PH0 } 3652 }, 3653 { 3654 RK3568_CLK_PCIEPHY2_REF, RK3568_PMUCRU_CLKSEL_CON(9), 3655 SEL(11, 11), 0, 3656 { RK3568_CLK_PCIEPHY2_OSC0, RK3568_CLK_PCIEPHY2_DIV }, 3657 SET_PARENT 3658 }, 3659 { 3660 RK3568_CLK_PDPMU, RK3568_PMUCRU_CLKSEL_CON(2), 3661 SEL(15, 15), 0, 3662 { RK3568_PLL_PPLL, 0 } 3663 }, 3664 { 3665 /* Sentinel */ 3666 } 3667 }; 3668 3669 void 3670 rk3568_pmu_init(struct rkclock_softc *sc) 3671 { 3672 int i; 3673 3674 /* The code below assumes all clocks are enabled. Check this!. */ 3675 for (i = 0; i <= 2; i++) { 3676 if (HREAD4(sc, RK3568_PMUCRU_GATE_CON(i)) != 0x00000000) { 3677 printf("CRU_GATE_CON%d: 0x%08x\n", i, 3678 HREAD4(sc, RK3568_CRU_GATE_CON(i))); 3679 } 3680 } 3681 3682 sc->sc_clocks = rk3568_pmu_clocks; 3683 } 3684 3685 int 3686 rk3568_pmu_set_pll(struct rkclock_softc *sc, bus_size_t base, uint32_t freq) 3687 { 3688 uint32_t fbdiv, postdiv1, postdiv2, refdiv; 3689 int mode_shift = -1; 3690 3691 switch (base) { 3692 case RK3568_PMUCRU_PPLL_CON(0): 3693 mode_shift = 0; 3694 break; 3695 case RK3568_PMUCRU_HPLL_CON(0): 3696 mode_shift = 2; 3697 break; 3698 } 3699 KASSERT(mode_shift != -1); 3700 3701 /* 3702 * It is not clear whether all combinations of the clock 3703 * dividers result in a stable clock. Therefore this function 3704 * only supports a limited set of PLL clock rates. 3705 */ 3706 switch (freq) { 3707 case 200000000U: 3708 postdiv1 = 3; postdiv2 = 4; refdiv = 1; 3709 break; 3710 default: 3711 printf("%s: %u Hz\n", __func__, freq); 3712 return -1; 3713 } 3714 3715 /* Calculate feedback divider. */ 3716 fbdiv = freq * postdiv1 * postdiv2 * refdiv / 24000000; 3717 3718 /* 3719 * Select slow mode to guarantee a stable clock while we're 3720 * adjusting the PLL. 3721 */ 3722 HWRITE4(sc, RK3568_PMUCRU_MODE_CON, 3723 (RK3328_CRU_CRU_MODE_MASK << 16 | 3724 RK3328_CRU_CRU_MODE_SLOW) << mode_shift); 3725 3726 /* Set PLL rate. */ 3727 HWRITE4(sc, base + 0x0000, 3728 RK3328_CRU_PLL_POSTDIV1_MASK << 16 | 3729 postdiv1 << RK3328_CRU_PLL_POSTDIV1_SHIFT | 3730 RK3328_CRU_PLL_FBDIV_MASK << 16 | 3731 fbdiv << RK3328_CRU_PLL_FBDIV_SHIFT); 3732 HWRITE4(sc, base + 0x0004, 3733 RK3328_CRU_PLL_DSMPD << 16 | RK3328_CRU_PLL_DSMPD | 3734 RK3328_CRU_PLL_POSTDIV2_MASK << 16 | 3735 postdiv2 << RK3328_CRU_PLL_POSTDIV2_SHIFT | 3736 RK3328_CRU_PLL_REFDIV_MASK << 16 | 3737 refdiv << RK3328_CRU_PLL_REFDIV_SHIFT); 3738 3739 /* Wait for PLL to stabilize. */ 3740 while ((HREAD4(sc, base + 0x0004) & RK3328_CRU_PLL_PLL_LOCK) == 0) 3741 delay(10); 3742 3743 /* Switch back to normal mode. */ 3744 HWRITE4(sc, RK3568_PMUCRU_MODE_CON, 3745 (RK3328_CRU_CRU_MODE_MASK << 16 | 3746 RK3328_CRU_CRU_MODE_NORMAL) << mode_shift); 3747 3748 return 0; 3749 } 3750 3751 uint32_t 3752 rk3568_pmu_get_frequency(void *cookie, uint32_t *cells) 3753 { 3754 struct rkclock_softc *sc = cookie; 3755 uint32_t idx = cells[0]; 3756 3757 switch (idx) { 3758 case RK3568_PLL_PPLL: 3759 return rk3328_get_pll(sc, RK3568_PMUCRU_PPLL_CON(0)); 3760 case RK3568_PLL_HPLL: 3761 return rk3328_get_pll(sc, RK3568_PMUCRU_HPLL_CON(0)); 3762 case RK3568_CLK_RTC32K_FRAC: 3763 return rk3399_get_frac(sc, RK3568_XIN24M, 3764 RK3568_PMUCRU_CLKSEL_CON(1)); 3765 case RK3568_PPLL_PH0: 3766 idx = RK3568_PLL_PPLL; 3767 return rk3568_get_frequency(sc, &idx) / 2; 3768 case RK3568_XIN32K: 3769 return 32768; 3770 case RK3568_XIN24M: 3771 return 24000000; 3772 default: 3773 break; 3774 } 3775 3776 return rkclock_get_frequency(sc, idx); 3777 } 3778 3779 int 3780 rk3568_pmu_set_frequency(void *cookie, uint32_t *cells, uint32_t freq) 3781 { 3782 struct rkclock_softc *sc = cookie; 3783 uint32_t idx = cells[0]; 3784 3785 switch (idx) { 3786 case RK3568_PLL_PPLL: 3787 return rk3568_pmu_set_pll(sc, RK3568_PMUCRU_PPLL_CON(0), freq); 3788 case RK3568_PLL_HPLL: 3789 return rk3568_pmu_set_pll(sc, RK3568_PMUCRU_HPLL_CON(0), freq); 3790 case RK3568_CLK_RTC32K_FRAC: 3791 return rk3399_set_frac(sc, RK3568_XIN24M, 3792 RK3568_PMUCRU_CLKSEL_CON(1), freq); 3793 default: 3794 break; 3795 } 3796 3797 return rkclock_set_frequency(sc, idx, freq); 3798 } 3799 3800 void 3801 rk3568_pmu_enable(void *cookie, uint32_t *cells, int on) 3802 { 3803 uint32_t idx = cells[0]; 3804 3805 switch (idx) { 3806 case RK3568_CLK_USBPHY0_REF: 3807 case RK3568_CLK_USBPHY1_REF: 3808 case RK3568_CLK_PCIEPHY0_REF: 3809 case RK3568_CLK_PCIEPHY1_REF: 3810 case RK3568_CLK_PCIEPHY2_REF: 3811 case RK3568_CLK_PCIE30PHY_REF_M: 3812 case RK3568_CLK_PCIE30PHY_REF_N: 3813 case RK3568_CLK_I2C0: 3814 case RK3568_SCLK_UART0: 3815 case RK3568_PCLK_I2C0: 3816 /* Enabled by default. */ 3817 break; 3818 default: 3819 printf("%s: 0x%08x\n", __func__, idx); 3820 break; 3821 } 3822 } 3823 3824 void 3825 rk3568_pmu_reset(void *cookie, uint32_t *cells, int on) 3826 { 3827 uint32_t idx = cells[0]; 3828 3829 printf("%s: 0x%08x\n", __func__, idx); 3830 } 3831 3832 /* 3833 * Rockchip RK3588 3834 */ 3835 3836 const struct rkclock rk3588_clocks[] = { 3837 { 3838 RK3588_ACLK_BUS_ROOT, RK3588_CRU_CLKSEL_CON(38), 3839 SEL(5, 5), DIV(4, 0), 3840 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 3841 }, 3842 { 3843 RK3588_CLK_UART1_SRC, RK3588_CRU_CLKSEL_CON(41), 3844 SEL(14, 14), DIV(13, 9), 3845 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 3846 }, 3847 { 3848 RK3588_CLK_UART1, RK3588_CRU_CLKSEL_CON(43), 3849 SEL(1, 0), 0, 3850 { RK3588_CLK_UART1_SRC, RK3588_CLK_UART1_FRAC, RK3588_XIN24M } 3851 }, 3852 { 3853 RK3588_SCLK_UART1, 0, 0, 0, 3854 { RK3588_CLK_UART1 } 3855 }, 3856 { 3857 RK3588_CLK_UART2_SRC, RK3588_CRU_CLKSEL_CON(43), 3858 SEL(7, 7), DIV(6, 2), 3859 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 3860 }, 3861 { 3862 RK3588_CLK_UART2, RK3588_CRU_CLKSEL_CON(45), 3863 SEL(1, 0), 0, 3864 { RK3588_CLK_UART2_SRC, RK3588_CLK_UART2_FRAC, RK3588_XIN24M } 3865 }, 3866 { 3867 RK3588_SCLK_UART2, 0, 0, 0, 3868 { RK3588_CLK_UART2 } 3869 }, 3870 { 3871 RK3588_CLK_UART3_SRC, RK3588_CRU_CLKSEL_CON(45), 3872 SEL(7, 7), DIV(6, 2), 3873 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 3874 }, 3875 { 3876 RK3588_CLK_UART3, RK3588_CRU_CLKSEL_CON(47), 3877 SEL(1, 0), 0, 3878 { RK3588_CLK_UART3_SRC, RK3588_CLK_UART3_FRAC, RK3588_XIN24M } 3879 }, 3880 { 3881 RK3588_SCLK_UART3, 0, 0, 0, 3882 { RK3588_CLK_UART3 } 3883 }, 3884 { 3885 RK3588_CLK_UART4_SRC, RK3588_CRU_CLKSEL_CON(47), 3886 SEL(7, 7), DIV(6, 2), 3887 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 3888 }, 3889 { 3890 RK3588_CLK_UART4, RK3588_CRU_CLKSEL_CON(49), 3891 SEL(1, 0), 0, 3892 { RK3588_CLK_UART4_SRC, RK3588_CLK_UART4_FRAC, RK3588_XIN24M } 3893 }, 3894 { 3895 RK3588_SCLK_UART4, 0, 0, 0, 3896 { RK3588_CLK_UART4 } 3897 }, 3898 { 3899 RK3588_CLK_UART5_SRC, RK3588_CRU_CLKSEL_CON(49), 3900 SEL(7, 7), DIV(6, 2), 3901 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 3902 }, 3903 { 3904 RK3588_CLK_UART5, RK3588_CRU_CLKSEL_CON(51), 3905 SEL(1, 0), 0, 3906 { RK3588_CLK_UART5_SRC, RK3588_CLK_UART5_FRAC, RK3588_XIN24M } 3907 }, 3908 { 3909 RK3588_SCLK_UART5, 0, 0, 0, 3910 { RK3588_CLK_UART5 } 3911 }, 3912 { 3913 RK3588_CLK_UART6_SRC, RK3588_CRU_CLKSEL_CON(51), 3914 SEL(7, 7), DIV(6, 2), 3915 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 3916 }, 3917 { 3918 RK3588_CLK_UART6, RK3588_CRU_CLKSEL_CON(53), 3919 SEL(1, 0), 0, 3920 { RK3588_CLK_UART6_SRC, RK3588_CLK_UART6_FRAC, RK3588_XIN24M } 3921 }, 3922 { 3923 RK3588_SCLK_UART6, 0, 0, 0, 3924 { RK3588_CLK_UART6 } 3925 }, 3926 { 3927 RK3588_CLK_UART7_SRC, RK3588_CRU_CLKSEL_CON(53), 3928 SEL(7, 7), DIV(6, 2), 3929 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 3930 }, 3931 { 3932 RK3588_CLK_UART7, RK3588_CRU_CLKSEL_CON(55), 3933 SEL(1, 0), 0, 3934 { RK3588_CLK_UART7_SRC, RK3588_CLK_UART7_FRAC, RK3588_XIN24M } 3935 }, 3936 { 3937 RK3588_SCLK_UART7, 0, 0, 0, 3938 { RK3588_CLK_UART7 } 3939 }, 3940 { 3941 RK3588_CLK_UART8_SRC, RK3588_CRU_CLKSEL_CON(55), 3942 SEL(7, 7), DIV(6, 2), 3943 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 3944 }, 3945 { 3946 RK3588_CLK_UART8, RK3588_CRU_CLKSEL_CON(57), 3947 SEL(1, 0), 0, 3948 { RK3588_CLK_UART8_SRC, RK3588_CLK_UART8_FRAC, RK3588_XIN24M } 3949 }, 3950 { 3951 RK3588_SCLK_UART8, 0, 0, 0, 3952 { RK3588_CLK_UART8 } 3953 }, 3954 { 3955 RK3588_CLK_UART9_SRC, RK3588_CRU_CLKSEL_CON(57), 3956 SEL(7, 7), DIV(6, 2), 3957 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 3958 }, 3959 { 3960 RK3588_CLK_UART9, RK3588_CRU_CLKSEL_CON(59), 3961 SEL(1, 0), 0, 3962 { RK3588_CLK_UART9_SRC, RK3588_CLK_UART9_FRAC, RK3588_XIN24M } 3963 }, 3964 { 3965 RK3588_SCLK_UART9, 0, 0, 0, 3966 { RK3588_CLK_UART9 } 3967 }, 3968 { 3969 RK3588_ACLK_CENTER_ROOT, RK3588_CRU_CLKSEL_CON(165), 3970 SEL(1, 0), 0, 3971 { RK3588_CLK_700M_SRC, RK3588_CLK_400M_SRC, 3972 RK3588_CLK_200M_SRC, RK3588_XIN24M } 3973 }, 3974 { 3975 RK3588_ACLK_CENTER_LOW_ROOT, RK3588_CRU_CLKSEL_CON(165), 3976 SEL(3, 2), 0, 3977 { RK3588_CLK_500M_SRC, RK3588_CLK_250M_SRC, 3978 RK3588_CLK_100M_SRC, RK3588_XIN24M } 3979 }, 3980 { 3981 RK3588_HCLK_CENTER_ROOT, RK3588_CRU_CLKSEL_CON(165), 3982 SEL(5, 4), 0, 3983 { RK3588_CLK_400M_SRC, RK3588_CLK_200M_SRC, 3984 RK3588_CLK_100M_SRC, RK3588_XIN24M } 3985 }, 3986 { 3987 RK3588_CLK_50M_SRC, RK3588_CRU_CLKSEL_CON(0), 3988 SEL(5, 5), DIV(4, 0), 3989 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 3990 }, 3991 { 3992 RK3588_CLK_100M_SRC, RK3588_CRU_CLKSEL_CON(0), 3993 SEL(11, 11), DIV(10, 6), 3994 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 3995 }, 3996 { 3997 RK3588_CLK_150M_SRC, RK3588_CRU_CLKSEL_CON(1), 3998 SEL(5, 5), DIV(4, 0), 3999 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 4000 }, 4001 { 4002 RK3588_CLK_200M_SRC, RK3588_CRU_CLKSEL_CON(1), 4003 SEL(11, 11), DIV(10, 6), 4004 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 4005 }, 4006 { 4007 RK3588_CLK_250M_SRC, RK3588_CRU_CLKSEL_CON(2), 4008 SEL(5, 5), DIV(4, 0), 4009 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 4010 }, 4011 { 4012 RK3588_CLK_400M_SRC, RK3588_CRU_CLKSEL_CON(3), 4013 SEL(11, 11), DIV(10, 6), 4014 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 4015 }, 4016 { 4017 RK3588_CLK_500M_SRC, RK3588_CRU_CLKSEL_CON(4), 4018 SEL(11, 11), DIV(10, 6), 4019 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 4020 }, 4021 { 4022 RK3588_CLK_700M_SRC, RK3588_CRU_CLKSEL_CON(6), 4023 SEL(5, 5), DIV(4, 0), 4024 { RK3588_PLL_GPLL, RK3588_PLL_SPLL } 4025 }, 4026 { 4027 RK3588_ACLK_TOP_ROOT, RK3588_CRU_CLKSEL_CON(8), 4028 SEL(6, 5), 0, 4029 { RK3588_PLL_GPLL, RK3588_PLL_CPLL, RK3588_PLL_AUPLL } 4030 }, 4031 { 4032 RK3588_PCLK_TOP_ROOT, RK3588_CRU_CLKSEL_CON(8), 4033 SEL(8, 7), 0, 4034 { RK3588_CLK_100M_SRC, RK3588_CLK_50M_SRC, RK3588_XIN24M } 4035 }, 4036 { 4037 RK3588_ACLK_LOW_TOP_ROOT, RK3588_CRU_CLKSEL_CON(8), 4038 SEL(14, 14), DIV(13, 9), 4039 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 4040 }, 4041 { 4042 RK3588_CLK_GPU_SRC, RK3588_CRU_CLKSEL_CON(158), 4043 SEL(7, 5), DIV(4, 0), 4044 { RK3588_PLL_GPLL, RK3588_PLL_CPLL, RK3588_PLL_AUPLL, 4045 RK3588_PLL_NPLL, RK3588_PLL_SPLL } 4046 }, 4047 { 4048 RK3588_CLK_GPU, 0, 0, 0, 4049 { RK3588_CLK_GPU_SRC }, 4050 SET_PARENT 4051 }, 4052 { 4053 RK3588_ACLK_VOP_ROOT, RK3588_CRU_CLKSEL_CON(110), 4054 SEL(7, 5), DIV(4, 0), 4055 { RK3588_PLL_GPLL, RK3588_PLL_CPLL, RK3588_PLL_AUPLL, 4056 RK3588_PLL_NPLL, RK3588_PLL_SPLL } 4057 }, 4058 { 4059 RK3588_ACLK_VOP, 0, 0, 0, 4060 { RK3588_ACLK_VOP_SUB_SRC }, 4061 SET_PARENT 4062 }, 4063 { 4064 RK3588_ACLK_VOP_SUB_SRC, RK3588_CRU_CLKSEL_CON(115), 4065 SEL(9, 9), 0, 4066 { RK3588_ACLK_VOP_ROOT, 0 /* RK3588_ACLK_VOP_DIV2_SRC */ }, 4067 SET_PARENT 4068 }, 4069 { 4070 RK3588_CLK_PMU1_50M_SRC, RK3588_PMUCRU_CLKSEL_CON(0), 4071 0, DIV(3, 0), 4072 { RK3588_CLK_PMU1_400M_SRC } 4073 }, 4074 { 4075 RK3588_CLK_PMU1_100M_SRC, RK3588_PMUCRU_CLKSEL_CON(0), 4076 0, DIV(6, 4), 4077 { RK3588_CLK_PMU1_400M_SRC } 4078 }, 4079 { 4080 RK3588_CLK_PMU1_200M_SRC, RK3588_PMUCRU_CLKSEL_CON(0), 4081 0, DIV(9, 7), 4082 { RK3588_CLK_PMU1_400M_SRC } 4083 }, 4084 { 4085 RK3588_CLK_PMU1_400M_SRC, RK3588_PMUCRU_CLKSEL_CON(1), 4086 SEL(5, 5), DIV(4, 0), 4087 { RK3588_CLK_400M_SRC, RK3588_XIN24M } 4088 }, 4089 { 4090 RK3588_PCLK_PMU1_ROOT, RK3588_PMUCRU_CLKSEL_CON(1), 4091 SEL(9, 8), 0, 4092 { RK3588_CLK_PMU1_100M_SRC, RK3588_CLK_PMU1_50M_SRC, 4093 RK3588_XIN24M } 4094 }, 4095 { 4096 RK3588_PCLK_PMU0_ROOT, 0, 0, 0, 4097 { RK3588_PCLK_PMU1_ROOT }, 4098 SET_PARENT 4099 }, 4100 { 4101 RK3588_HCLK_PMU_CM0_ROOT, RK3588_PMUCRU_CLKSEL_CON(1), 4102 SEL(11, 10), 0, 4103 { RK3588_CLK_PMU1_400M_SRC, RK3588_CLK_PMU1_200M_SRC, 4104 RK3588_CLK_PMU1_100M_SRC, RK3588_XIN24M } 4105 }, 4106 { 4107 RK3588_CLK_UART0_SRC, RK3588_PMUCRU_CLKSEL_CON(3), 4108 0, DIV(11, 7), 4109 { RK3588_PLL_CPLL } 4110 }, 4111 { 4112 RK3588_CLK_UART0, RK3588_PMUCRU_CLKSEL_CON(5), 4113 SEL(1, 0), 0, 4114 { RK3588_CLK_UART0_SRC, RK3588_CLK_UART0_FRAC, RK3588_XIN24M } 4115 }, 4116 { 4117 RK3588_SCLK_UART0, 0, 0, 0, 4118 { RK3588_CLK_UART0 } 4119 }, 4120 { 4121 RK3588_CLK_REF_PIPE_PHY0_OSC_SRC, 0, 0, 0, 4122 { RK3588_XIN24M } 4123 }, 4124 { 4125 RK3588_CLK_REF_PIPE_PHY0_PLL_SRC, RK3588_CRU_CLKSEL_CON(176), 4126 0, DIV(5, 0), 4127 { RK3588_PLL_PPLL } 4128 }, 4129 { 4130 RK3588_CLK_REF_PIPE_PHY0, RK3588_CRU_CLKSEL_CON(177), 4131 SEL(6, 6), 0, 4132 { RK3588_CLK_REF_PIPE_PHY0_OSC_SRC, 4133 RK3588_CLK_REF_PIPE_PHY0_PLL_SRC }, 4134 }, 4135 { 4136 /* Sentinel */ 4137 } 4138 }; 4139 4140 /* Certain test clocks are disabled. */ 4141 const uint32_t rk3588_gates[78] = { 4142 [2] = 0x00000050, 4143 [22] = 0x00000200, 4144 [25] = 0x00000200, 4145 [29] = 0x00000004, 4146 [66] = 0x00000004, 4147 }; 4148 4149 void 4150 rk3588_init(struct rkclock_softc *sc) 4151 { 4152 int i; 4153 4154 /* The code below assumes all clocks are enabled. Check this!. */ 4155 for (i = 0; i < nitems(rk3588_gates); i++) { 4156 if (HREAD4(sc, RK3588_CRU_GATE_CON(i)) != rk3588_gates[i]) { 4157 printf("CRU_GATE_CON%d: 0x%08x\n", i, 4158 HREAD4(sc, RK3588_CRU_GATE_CON(i))); 4159 } 4160 } 4161 4162 sc->sc_clocks = rk3588_clocks; 4163 } 4164 4165 int 4166 rk3588_set_pll(struct rkclock_softc *sc, bus_size_t base, uint32_t freq) 4167 { 4168 uint32_t p, m, s, k; 4169 int mode_shift = -1; 4170 4171 switch (base) { 4172 case RK3588_CRU_AUPLL_CON(0): 4173 mode_shift = 6; 4174 break; 4175 case RK3588_CRU_GPLL_CON(0): 4176 mode_shift = 2; 4177 break; 4178 case RK3588_CRU_NPLL_CON(0): 4179 mode_shift = 0; 4180 break; 4181 case RK3588_PHPTOPCRU_PPLL_CON(0): 4182 mode_shift = 10; 4183 break; 4184 } 4185 KASSERT(mode_shift != -1); 4186 4187 /* 4188 * It is not clear whether all combinations of the clock 4189 * dividers result in a stable clock. Therefore this function 4190 * only supports a limited set of PLL clock rates. 4191 */ 4192 switch (freq) { 4193 case 1188000000U: 4194 p = 2; m = 198; s = 1; k = 0; 4195 break; 4196 case 850000000U: 4197 p = 3; m = 425; s = 2; k = 0; 4198 break; 4199 case 786432000U: 4200 p = 2; m = 262; s = 2; k = 9437; 4201 break; 4202 case 100000000U: 4203 p = 3; m = 400; s = 5; k = 0; 4204 break; 4205 default: 4206 printf("%s: %u Hz\n", __func__, freq); 4207 return -1; 4208 } 4209 4210 /* 4211 * Select slow mode to guarantee a stable clock while we're 4212 * adjusting the PLL. 4213 */ 4214 HWRITE4(sc, RK3588_CRU_MODE_CON, 4215 (RK3588_CRU_MODE_MASK << 16 |RK3588_CRU_MODE_SLOW) << mode_shift); 4216 4217 /* Power down PLL. */ 4218 HWRITE4(sc, base + 0x0004, 4219 RK3588_CRU_PLL_RESETB << 16 | RK3588_CRU_PLL_RESETB); 4220 4221 /* Set PLL rate. */ 4222 HWRITE4(sc, base + 0x0000, 4223 RK3588_CRU_PLL_M_MASK << 16 | m << RK3588_CRU_PLL_M_SHIFT); 4224 HWRITE4(sc, base + 0x0004, 4225 RK3588_CRU_PLL_S_MASK << 16 | s << RK3588_CRU_PLL_S_SHIFT | 4226 RK3588_CRU_PLL_P_MASK << 16 | p << RK3588_CRU_PLL_P_SHIFT); 4227 HWRITE4(sc, base + 0x0008, 4228 RK3588_CRU_PLL_K_MASK << 16 | k << RK3588_CRU_PLL_K_SHIFT); 4229 4230 /* Power up PLL. */ 4231 HWRITE4(sc, base + 0x0004, RK3588_CRU_PLL_RESETB << 16); 4232 4233 /* Wait for PLL to stabilize. */ 4234 while ((HREAD4(sc, base + 0x0018) & RK3588_CRU_PLL_PLL_LOCK) == 0) 4235 delay(10); 4236 4237 /* Switch back to normal mode. */ 4238 HWRITE4(sc, RK3588_CRU_MODE_CON, 4239 (RK3588_CRU_MODE_MASK << 16 | RK3588_CRU_MODE_NORMAL) << mode_shift); 4240 4241 return 0; 4242 } 4243 4244 uint32_t 4245 rk3588_get_pll(struct rkclock_softc *sc, bus_size_t base) 4246 { 4247 uint64_t freq, frac; 4248 uint32_t k, m, p, s; 4249 uint32_t reg; 4250 4251 reg = HREAD4(sc, base); 4252 m = (reg & RK3588_CRU_PLL_M_MASK) >> RK3588_CRU_PLL_M_SHIFT; 4253 reg = HREAD4(sc, base + 4); 4254 p = (reg & RK3588_CRU_PLL_P_MASK) >> RK3588_CRU_PLL_P_SHIFT; 4255 s = (reg & RK3588_CRU_PLL_S_MASK) >> RK3588_CRU_PLL_S_SHIFT; 4256 reg = HREAD4(sc, base + 8); 4257 k = (reg & RK3588_CRU_PLL_K_MASK) >> RK3588_CRU_PLL_K_SHIFT; 4258 4259 freq = (24000000ULL * m) / p; 4260 if (k) { 4261 frac = ((24000000ULL * k) / (p * 65535)); 4262 freq += frac; 4263 } 4264 4265 return freq >> s; 4266 } 4267 4268 uint32_t 4269 rk3588_get_frequency(void *cookie, uint32_t *cells) 4270 { 4271 struct rkclock_softc *sc = cookie; 4272 uint32_t idx = cells[0]; 4273 uint32_t freq; 4274 4275 switch (idx) { 4276 case RK3588_PLL_AUPLL: 4277 return rk3588_get_pll(sc, RK3588_CRU_AUPLL_CON(0)); 4278 case RK3588_PLL_CPLL: 4279 return rk3588_get_pll(sc, RK3588_CRU_CPLL_CON(0)); 4280 case RK3588_PLL_GPLL: 4281 return rk3588_get_pll(sc, RK3588_CRU_GPLL_CON(0)); 4282 case RK3588_PLL_NPLL: 4283 return rk3588_get_pll(sc, RK3588_CRU_NPLL_CON(0)); 4284 case RK3588_PLL_PPLL: 4285 return rk3588_get_pll(sc, RK3588_PHPTOPCRU_PPLL_CON(0)); 4286 case RK3588_PLL_SPLL: 4287 return rkclock_external_frequency("spll"); 4288 case RK3588_XIN24M: 4289 return 24000000; 4290 default: 4291 break; 4292 } 4293 4294 freq = rkclock_get_frequency(sc, idx); 4295 return freq; 4296 } 4297 4298 int 4299 rk3588_set_frequency(void *cookie, uint32_t *cells, uint32_t freq) 4300 { 4301 struct rkclock_softc *sc = cookie; 4302 uint32_t idx = cells[0]; 4303 4304 switch (idx) { 4305 case RK3588_PLL_AUPLL: 4306 return rk3588_set_pll(sc, RK3588_CRU_AUPLL_CON(0), freq); 4307 case RK3588_PLL_GPLL: 4308 return rk3588_set_pll(sc, RK3588_CRU_GPLL_CON(0), freq); 4309 case RK3588_PLL_NPLL: 4310 return rk3588_set_pll(sc, RK3588_CRU_NPLL_CON(0), freq); 4311 case RK3588_PLL_PPLL: 4312 return rk3588_set_pll(sc, RK3588_PHPTOPCRU_PPLL_CON(0), freq); 4313 default: 4314 break; 4315 } 4316 4317 return rkclock_set_frequency(sc, idx, freq); 4318 } 4319 4320 void 4321 rk3588_enable(void *cookie, uint32_t *cells, int on) 4322 { 4323 uint32_t idx = cells[0]; 4324 4325 /* All clocks are enabled upon hardware reset. */ 4326 if (!on) { 4327 printf("%s: 0x%08x\n", __func__, idx); 4328 return; 4329 } 4330 } 4331 4332 void 4333 rk3588_reset(void *cookie, uint32_t *cells, int on) 4334 { 4335 struct rkclock_softc *sc = cookie; 4336 uint32_t idx = cells[0]; 4337 uint32_t bit, mask, reg; 4338 4339 switch (idx) { 4340 case RK3588_SRST_PCIE4_POWER_UP: 4341 reg = RK3588_CRU_SOFTRST_CON(33); 4342 bit = 1; 4343 break; 4344 case RK3588_SRST_REF_PIPE_PHY0: 4345 reg = RK3588_CRU_SOFTRST_CON(77); 4346 bit = 6; 4347 break; 4348 case RK3588_SRST_P_PCIE2_PHY0: 4349 reg = RK3588_PHPTOPCRU_SOFTRST_CON(0); 4350 bit = 5; 4351 break; 4352 default: 4353 printf("%s: 0x%08x\n", __func__, idx); 4354 return; 4355 } 4356 4357 mask = (1 << bit); 4358 HWRITE4(sc, reg, mask << 16 | (on ? mask : 0)); 4359 } 4360