1 /* $OpenBSD: rkclock.c,v 1.84 2023/11/26 13:47:45 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_CLK_USB2PHY0_REF: 2956 HWRITE4(sc, RK3399_CRU_CLKGATE_CON(6), (5 << 0) << 16); 2957 break; 2958 case RK3399_CLK_USB2PHY1_REF: 2959 HWRITE4(sc, RK3399_CRU_CLKGATE_CON(6), (6 << 0) << 16); 2960 break; 2961 case RK3399_CLK_UPHY0_TCPDPHY_REF: 2962 HWRITE4(sc, RK3399_CRU_CLKGATE_CON(13), (4 << 0) << 16); 2963 break; 2964 case RK3399_CLK_UPHY0_TCPDCORE: 2965 HWRITE4(sc, RK3399_CRU_CLKGATE_CON(13), (5 << 0) << 16); 2966 break; 2967 case RK3399_CLK_UPHY1_TCPDPHY_REF: 2968 HWRITE4(sc, RK3399_CRU_CLKGATE_CON(13), (6 << 0) << 16); 2969 break; 2970 case RK3399_CLK_UPHY1_TCPDCORE: 2971 HWRITE4(sc, RK3399_CRU_CLKGATE_CON(13), (7 << 0) << 16); 2972 break; 2973 case RK3399_ACLK_GMAC: 2974 HWRITE4(sc, RK3399_CRU_CLKGATE_CON(32), (1 << 0) << 16); 2975 break; 2976 case RK3399_PCLK_GMAC: 2977 HWRITE4(sc, RK3399_CRU_CLKGATE_CON(32), (1 << 2) << 16); 2978 break; 2979 case RK3399_CLK_MAC: 2980 HWRITE4(sc, RK3399_CRU_CLKGATE_CON(5), (1 << 5) << 16); 2981 break; 2982 case RK3399_CLK_MAC_RX: 2983 HWRITE4(sc, RK3399_CRU_CLKGATE_CON(5), (1 << 8) << 16); 2984 break; 2985 case RK3399_CLK_MAC_TX: 2986 HWRITE4(sc, RK3399_CRU_CLKGATE_CON(5), (1 << 9) << 16); 2987 break; 2988 } 2989 } 2990 2991 void 2992 rk3399_reset(void *cookie, uint32_t *cells, int on) 2993 { 2994 struct rkclock_softc *sc = cookie; 2995 uint32_t idx = cells[0]; 2996 uint32_t mask = (1 << (idx % 16)); 2997 2998 HWRITE4(sc, RK3399_CRU_SOFTRST_CON(idx / 16), 2999 mask << 16 | (on ? mask : 0)); 3000 } 3001 3002 /* PMUCRU */ 3003 3004 const struct rkclock rk3399_pmu_clocks[] = { 3005 { 3006 RK3399_CLK_I2C0, RK3399_PMUCRU_CLKSEL_CON(2), 3007 0, DIV(6, 0), 3008 { RK3399_PLL_PPLL } 3009 }, 3010 { 3011 RK3399_CLK_I2C4, RK3399_PMUCRU_CLKSEL_CON(3), 3012 0, DIV(6, 0), 3013 { RK3399_PLL_PPLL } 3014 }, 3015 { 3016 RK3399_CLK_I2C8, RK3399_PMUCRU_CLKSEL_CON(2), 3017 0, DIV(14, 8), 3018 { RK3399_PLL_PPLL } 3019 }, 3020 { 3021 RK3399_PCLK_RKPWM, RK3399_PMUCRU_CLKSEL_CON(0), 3022 0, DIV(6, 0), 3023 { RK3399_PLL_PPLL } 3024 }, 3025 { 3026 /* Sentinel */ 3027 } 3028 }; 3029 3030 void 3031 rk3399_pmu_init(struct rkclock_softc *sc) 3032 { 3033 sc->sc_clocks = rk3399_pmu_clocks; 3034 rk3399_pmucru_sc = sc; 3035 } 3036 3037 uint32_t 3038 rk3399_pmu_get_frequency(void *cookie, uint32_t *cells) 3039 { 3040 struct rkclock_softc *sc = cookie; 3041 uint32_t idx = cells[0]; 3042 3043 switch (idx) { 3044 case RK3399_PLL_PPLL: 3045 return rk3399_get_pll(sc, RK3399_PMUCRU_PPLL_CON(0)); 3046 default: 3047 break; 3048 } 3049 3050 return rkclock_get_frequency(sc, idx); 3051 } 3052 3053 int 3054 rk3399_pmu_set_frequency(void *cookie, uint32_t *cells, uint32_t freq) 3055 { 3056 struct rkclock_softc *sc = cookie; 3057 uint32_t idx = cells[0]; 3058 3059 switch (idx) { 3060 case RK3399_PLL_PPLL: 3061 return rk3399_set_pll(sc, RK3399_PMUCRU_PPLL_CON(0), freq); 3062 default: 3063 break; 3064 } 3065 3066 return rkclock_set_frequency(sc, idx, freq); 3067 } 3068 3069 void 3070 rk3399_pmu_enable(void *cookie, uint32_t *cells, int on) 3071 { 3072 uint32_t idx = cells[0]; 3073 3074 switch (idx) { 3075 case RK3399_CLK_I2C0: 3076 case RK3399_CLK_I2C4: 3077 case RK3399_CLK_I2C8: 3078 case RK3399_PCLK_I2C0: 3079 case RK3399_PCLK_I2C4: 3080 case RK3399_PCLK_I2C8: 3081 case RK3399_PCLK_RKPWM: 3082 /* Enabled by default. */ 3083 break; 3084 default: 3085 printf("%s: 0x%08x\n", __func__, idx); 3086 break; 3087 } 3088 } 3089 3090 void 3091 rk3399_pmu_reset(void *cookie, uint32_t *cells, int on) 3092 { 3093 uint32_t idx = cells[0]; 3094 3095 printf("%s: 0x%08x\n", __func__, idx); 3096 } 3097 3098 /* 3099 * Rockchip RK3568 3100 */ 3101 3102 const struct rkclock rk3568_clocks[] = { 3103 { 3104 RK3568_BCLK_EMMC, RK3568_CRU_CLKSEL_CON(28), 3105 SEL(9, 8), 0, 3106 { RK3568_GPLL_200M, RK3568_GPLL_150M, RK3568_CPLL_125M } 3107 }, 3108 { 3109 RK3568_CCLK_EMMC, RK3568_CRU_CLKSEL_CON(28), 3110 SEL(14, 12), 0, 3111 { RK3568_XIN24M, RK3568_GPLL_200M, RK3568_GPLL_150M, 3112 RK3568_CPLL_100M, RK3568_CPLL_50M, RK3568_CLK_OSC0_DIV_375K } 3113 }, 3114 { 3115 RK3568_TCLK_EMMC, 0, 0, 0, 3116 { RK3568_XIN24M } 3117 }, 3118 3119 { 3120 RK3568_ACLK_PHP, RK3568_CRU_CLKSEL_CON(30), 3121 SEL(1, 0), 0, 3122 { RK3568_GPLL_300M, RK3568_GPLL_200M, 3123 RK3568_GPLL_100M, RK3568_XIN24M } 3124 }, 3125 { 3126 RK3568_PCLK_PHP, RK3568_CRU_CLKSEL_CON(30), 3127 0, DIV(7, 4), 3128 { RK3568_ACLK_PHP } 3129 }, 3130 { 3131 RK3568_CLK_SDMMC0, RK3568_CRU_CLKSEL_CON(30), 3132 SEL(10, 8), 0, 3133 { RK3568_XIN24M, RK3568_GPLL_400M, RK3568_GPLL_300M, 3134 RK3568_CPLL_100M, RK3568_CPLL_50M, RK3568_CLK_OSC0_DIV_750K } 3135 }, 3136 { 3137 RK3568_CLK_SDMMC1, RK3568_CRU_CLKSEL_CON(30), 3138 SEL(14, 12), 0, 3139 { RK3568_XIN24M, RK3568_GPLL_400M, RK3568_GPLL_300M, 3140 RK3568_CPLL_100M, RK3568_CPLL_50M, RK3568_CLK_OSC0_DIV_750K } 3141 }, 3142 { 3143 RK3568_CLK_SDMMC2, RK3568_CRU_CLKSEL_CON(32), 3144 SEL(10, 8), 0, 3145 { RK3568_XIN24M, RK3568_GPLL_400M, RK3568_GPLL_300M, 3146 RK3568_CPLL_100M, RK3568_CPLL_50M, RK3568_CLK_OSC0_DIV_750K } 3147 }, 3148 { 3149 RK3568_ACLK_GMAC0, 0, 0, 0, 3150 { RK3568_ACLK_PHP } 3151 }, 3152 { 3153 RK3568_PCLK_GMAC0, 0, 0, 0, 3154 { RK3568_PCLK_PHP } 3155 }, 3156 { 3157 RK3568_CLK_MAC0_2TOP, RK3568_CRU_CLKSEL_CON(31), 3158 SEL(9, 8), 0, 3159 { RK3568_CPLL_125M, RK3568_CPLL_50M, 3160 RK3568_CPLL_25M, RK3568_XIN24M } 3161 }, 3162 { 3163 RK3568_CLK_MAC0_REFOUT, 0, 0, 0, 3164 { RK3568_CLK_MAC0_2TOP } 3165 }, 3166 { 3167 RK3568_CLK_GMAC0_PTP_REF, RK3568_CRU_CLKSEL_CON(31), 3168 SEL(13, 12), 0, 3169 { RK3568_CPLL_62P5M, RK3568_GPLL_100M, 3170 RK3568_CPLL_50M, RK3568_XIN24M } 3171 }, 3172 { 3173 RK3568_ACLK_USB, RK3568_CRU_CLKSEL_CON(32), 3174 SEL(1, 0), 0, 3175 { RK3568_GPLL_300M, RK3568_GPLL_200M, 3176 RK3568_GPLL_100M, RK3568_XIN24M } 3177 }, 3178 { 3179 RK3568_PCLK_USB, RK3568_CRU_CLKSEL_CON(32), 3180 0, DIV(7, 4), 3181 { RK3568_ACLK_USB } 3182 }, 3183 { 3184 RK3568_ACLK_GMAC1, 0, 0, 0, 3185 { RK3568_ACLK_USB } 3186 }, 3187 { 3188 RK3568_PCLK_GMAC1, 0, 0, 0, 3189 { RK3568_PCLK_USB } 3190 }, 3191 { 3192 RK3568_CLK_MAC1_2TOP, RK3568_CRU_CLKSEL_CON(33), 3193 SEL(9, 8), 0, 3194 { RK3568_CPLL_125M, RK3568_CPLL_50M, 3195 RK3568_CPLL_25M, RK3568_XIN24M } 3196 }, 3197 { 3198 RK3568_CLK_MAC1_REFOUT, 0, 0, 0, 3199 { RK3568_CLK_MAC1_2TOP } 3200 }, 3201 { 3202 RK3568_CLK_GMAC1_PTP_REF, RK3568_CRU_CLKSEL_CON(33), 3203 SEL(13, 12), 0, 3204 { RK3568_CPLL_62P5M, RK3568_GPLL_100M, 3205 RK3568_CPLL_50M, RK3568_XIN24M } 3206 }, 3207 { 3208 RK3568_CLK_TSADC_TSEN, RK3568_CRU_CLKSEL_CON(51), 3209 SEL(5, 4), DIV(2, 0), 3210 { RK3568_XIN24M, RK3568_GPLL_100M, RK3568_CPLL_100M } 3211 }, 3212 { 3213 RK3568_CLK_TSADC, RK3568_CRU_CLKSEL_CON(51), 3214 0, DIV(14, 8), 3215 { RK3568_CLK_TSADC_TSEN } 3216 }, 3217 { 3218 RK3568_SCLK_UART1, RK3568_CRU_CLKSEL_CON(52), 3219 SEL(13, 12), 0, 3220 { 0, 0, RK3568_XIN24M } 3221 }, 3222 { 3223 RK3568_SCLK_UART2, RK3568_CRU_CLKSEL_CON(54), 3224 SEL(13, 12), 0, 3225 { 0, 0, RK3568_XIN24M } 3226 }, 3227 { 3228 RK3568_SCLK_UART3, RK3568_CRU_CLKSEL_CON(56), 3229 SEL(13, 12), 0, 3230 { 0, 0, RK3568_XIN24M } 3231 }, 3232 { 3233 RK3568_SCLK_UART4, RK3568_CRU_CLKSEL_CON(58), 3234 SEL(13, 12), 0, 3235 { 0, 0, RK3568_XIN24M } 3236 }, 3237 { 3238 RK3568_SCLK_UART5, RK3568_CRU_CLKSEL_CON(60), 3239 SEL(13, 12), 0, 3240 { 0, 0, RK3568_XIN24M } 3241 }, 3242 { 3243 RK3568_SCLK_UART6, RK3568_CRU_CLKSEL_CON(62), 3244 SEL(13, 12), 0, 3245 { 0, 0, RK3568_XIN24M } 3246 }, 3247 { 3248 RK3568_SCLK_UART7, RK3568_CRU_CLKSEL_CON(64), 3249 SEL(13, 12), 0, 3250 { 0, 0, RK3568_XIN24M } 3251 }, 3252 { 3253 RK3568_SCLK_UART8, RK3568_CRU_CLKSEL_CON(66), 3254 SEL(13, 12), 0, 3255 { 0, 0, RK3568_XIN24M } 3256 }, 3257 { 3258 RK3568_SCLK_UART9, RK3568_CRU_CLKSEL_CON(68), 3259 SEL(13, 12), 0, 3260 { 0, 0, RK3568_XIN24M } 3261 }, 3262 { 3263 RK3568_CLK_I2C, RK3568_CRU_CLKSEL_CON(71), 3264 SEL(9, 8), 0, 3265 { 0, 0, RK3568_XIN24M } 3266 }, 3267 { 3268 RK3568_CLK_I2C1, 0, 0, 0, 3269 { RK3568_CLK_I2C } 3270 }, 3271 { 3272 RK3568_CLK_I2C2, 0, 0, 0, 3273 { RK3568_CLK_I2C } 3274 }, 3275 { 3276 RK3568_CLK_I2C3, 0, 0, 0, 3277 { RK3568_CLK_I2C } 3278 }, 3279 { 3280 RK3568_CLK_I2C4, 0, 0, 0, 3281 { RK3568_CLK_I2C } 3282 }, 3283 { 3284 RK3568_CLK_I2C5, 0, 0, 0, 3285 { RK3568_CLK_I2C } 3286 }, 3287 { 3288 RK3568_SCLK_GMAC0, RK3568_CRU_CLKSEL_CON(31), 3289 SEL(2, 2), 0, 3290 { RK3568_CLK_MAC0_2TOP, RK3568_GMAC0_CLKIN } 3291 }, 3292 { 3293 RK3568_SCLK_GMAC0_RGMII_SPEED, RK3568_CRU_CLKSEL_CON(31), 3294 SEL(5, 4), 0, 3295 { RK3568_SCLK_GMAC0, RK3568_SCLK_GMAC0, 3296 RK3568_SCLK_GMAC0_DIV_50, RK3568_SCLK_GMAC0_DIV_5 } 3297 }, 3298 { 3299 RK3568_SCLK_GMAC0_RMII_SPEED, RK3568_CRU_CLKSEL_CON(31), 3300 SEL(3, 3), 0, 3301 { RK3568_SCLK_GMAC0_DIV_20, RK3568_SCLK_GMAC0_DIV_2 } 3302 }, 3303 { 3304 RK3568_SCLK_GMAC0_RX_TX, RK3568_CRU_CLKSEL_CON(31), 3305 SEL(1, 0), 0, 3306 { RK3568_SCLK_GMAC0_RGMII_SPEED, RK3568_SCLK_GMAC0_RMII_SPEED } 3307 }, 3308 { 3309 RK3568_SCLK_GMAC1, RK3568_CRU_CLKSEL_CON(33), 3310 SEL(2, 2), 0, 3311 { RK3568_CLK_MAC1_2TOP, RK3568_GMAC1_CLKIN } 3312 }, 3313 { 3314 RK3568_SCLK_GMAC1_RGMII_SPEED, RK3568_CRU_CLKSEL_CON(33), 3315 SEL(5, 4), 0, 3316 { RK3568_SCLK_GMAC1, RK3568_SCLK_GMAC1, 3317 RK3568_SCLK_GMAC1_DIV_50, RK3568_SCLK_GMAC1_DIV_5 } 3318 }, 3319 { 3320 RK3568_SCLK_GMAC1_RMII_SPEED, RK3568_CRU_CLKSEL_CON(33), 3321 SEL(3, 3), 0, 3322 { RK3568_SCLK_GMAC1_DIV_20, RK3568_SCLK_GMAC1_DIV_2 } 3323 }, 3324 { 3325 RK3568_SCLK_GMAC1_RX_TX, RK3568_CRU_CLKSEL_CON(33), 3326 SEL(1, 0), 0, 3327 { RK3568_SCLK_GMAC1_RGMII_SPEED, RK3568_SCLK_GMAC1_RMII_SPEED } 3328 }, 3329 { 3330 RK3568_CPLL_125M, RK3568_CRU_CLKSEL_CON(80), 3331 0, DIV(4, 0), 3332 { RK3568_PLL_CPLL } 3333 }, 3334 { 3335 RK3568_CPLL_62P5M, RK3568_CRU_CLKSEL_CON(80), 3336 0, DIV(12, 8), 3337 { RK3568_PLL_CPLL } 3338 }, 3339 { 3340 RK3568_CPLL_50M, RK3568_CRU_CLKSEL_CON(81), 3341 0, DIV(4, 0), 3342 { RK3568_PLL_CPLL } 3343 }, 3344 { 3345 RK3568_CPLL_25M, RK3568_CRU_CLKSEL_CON(81), 3346 0, DIV(13, 8), 3347 { RK3568_PLL_CPLL } 3348 }, 3349 { 3350 RK3568_CPLL_100M, RK3568_CRU_CLKSEL_CON(82), 3351 0, DIV(4, 0), 3352 { RK3568_PLL_CPLL } 3353 }, 3354 { 3355 RK3568_GPLL_400M, RK3568_CRU_CLKSEL_CON(75), 3356 0, DIV(4, 0), 3357 { RK3568_PLL_GPLL } 3358 }, 3359 { 3360 RK3568_GPLL_300M, RK3568_CRU_CLKSEL_CON(75), 3361 0, DIV(12, 8), 3362 { RK3568_PLL_GPLL } 3363 }, 3364 { 3365 RK3568_GPLL_200M, RK3568_CRU_CLKSEL_CON(76), 3366 0, DIV(4, 0), 3367 { RK3568_PLL_GPLL } 3368 }, 3369 { 3370 RK3568_GPLL_150M, RK3568_CRU_CLKSEL_CON(76), 3371 0, DIV(12, 5), 3372 { RK3568_PLL_GPLL } 3373 }, 3374 { 3375 RK3568_GPLL_100M, RK3568_CRU_CLKSEL_CON(77), 3376 0, DIV(4, 0), 3377 { RK3568_PLL_GPLL } 3378 }, 3379 { 3380 RK3568_CLK_OSC0_DIV_750K, RK3568_CRU_CLKSEL_CON(82), 3381 0, DIV(13, 8), 3382 { RK3568_XIN24M } 3383 }, 3384 { 3385 /* Sentinel */ 3386 } 3387 }; 3388 3389 void 3390 rk3568_init(struct rkclock_softc *sc) 3391 { 3392 int i; 3393 3394 /* The code below assumes all clocks are enabled. Check this!. */ 3395 for (i = 0; i <= 35; i++) { 3396 if (HREAD4(sc, RK3568_CRU_GATE_CON(i)) != 0x00000000) { 3397 printf("CRU_GATE_CON%d: 0x%08x\n", i, 3398 HREAD4(sc, RK3568_CRU_GATE_CON(i))); 3399 } 3400 } 3401 3402 sc->sc_clocks = rk3568_clocks; 3403 } 3404 3405 int 3406 rk3568_set_pll(struct rkclock_softc *sc, bus_size_t base, uint32_t freq) 3407 { 3408 uint32_t fbdiv, postdiv1, postdiv2, refdiv; 3409 int mode_shift = -1; 3410 3411 switch (base) { 3412 case RK3568_CRU_APLL_CON(0): 3413 mode_shift = 0; 3414 break; 3415 case RK3568_CRU_DPLL_CON(0): 3416 mode_shift = 2; 3417 break; 3418 case RK3568_CRU_CPLL_CON(0): 3419 mode_shift = 4; 3420 break; 3421 case RK3568_CRU_GPLL_CON(0): 3422 mode_shift = 6; 3423 break; 3424 case RK3568_CRU_NPLL_CON(0): 3425 mode_shift = 10; 3426 break; 3427 case RK3568_CRU_VPLL_CON(0): 3428 mode_shift = 12; 3429 break; 3430 } 3431 KASSERT(mode_shift != -1); 3432 3433 /* 3434 * It is not clear whether all combinations of the clock 3435 * dividers result in a stable clock. Therefore this function 3436 * only supports a limited set of PLL clock rates. 3437 */ 3438 switch (freq) { 3439 case 1200000000U: 3440 postdiv1 = 2; postdiv2 = refdiv = 1; 3441 break; 3442 default: 3443 printf("%s: %u Hz\n", __func__, freq); 3444 return -1; 3445 } 3446 3447 /* Calculate feedback divider. */ 3448 fbdiv = freq * postdiv1 * postdiv2 * refdiv / 24000000; 3449 3450 /* 3451 * Select slow mode to guarantee a stable clock while we're 3452 * adjusting the PLL. 3453 */ 3454 HWRITE4(sc, RK3568_CRU_MODE_CON, 3455 (RK3328_CRU_CRU_MODE_MASK << 16 | 3456 RK3328_CRU_CRU_MODE_SLOW) << mode_shift); 3457 3458 /* Set PLL rate. */ 3459 HWRITE4(sc, base + 0x0000, 3460 RK3328_CRU_PLL_POSTDIV1_MASK << 16 | 3461 postdiv1 << RK3328_CRU_PLL_POSTDIV1_SHIFT | 3462 RK3328_CRU_PLL_FBDIV_MASK << 16 | 3463 fbdiv << RK3328_CRU_PLL_FBDIV_SHIFT); 3464 HWRITE4(sc, base + 0x0004, 3465 RK3328_CRU_PLL_DSMPD << 16 | RK3328_CRU_PLL_DSMPD | 3466 RK3328_CRU_PLL_POSTDIV2_MASK << 16 | 3467 postdiv2 << RK3328_CRU_PLL_POSTDIV2_SHIFT | 3468 RK3328_CRU_PLL_REFDIV_MASK << 16 | 3469 refdiv << RK3328_CRU_PLL_REFDIV_SHIFT); 3470 3471 /* Wait for PLL to stabilize. */ 3472 while ((HREAD4(sc, base + 0x0004) & RK3328_CRU_PLL_PLL_LOCK) == 0) 3473 delay(10); 3474 3475 /* Switch back to normal mode. */ 3476 HWRITE4(sc, RK3568_CRU_MODE_CON, 3477 (RK3328_CRU_CRU_MODE_MASK << 16 | 3478 RK3328_CRU_CRU_MODE_NORMAL) << mode_shift); 3479 3480 return 0; 3481 } 3482 3483 uint32_t 3484 rk3568_get_frequency(void *cookie, uint32_t *cells) 3485 { 3486 struct rkclock_softc *sc = cookie; 3487 uint32_t idx = cells[0]; 3488 3489 switch (idx) { 3490 case RK3568_PLL_APLL: 3491 return rk3328_get_pll(sc, RK3568_CRU_APLL_CON(0)); 3492 case RK3568_PLL_DPLL: 3493 return rk3328_get_pll(sc, RK3568_CRU_DPLL_CON(0)); 3494 case RK3568_PLL_CPLL: 3495 return rk3328_get_pll(sc, RK3568_CRU_CPLL_CON(0)); 3496 case RK3568_PLL_GPLL: 3497 return rk3328_get_pll(sc, RK3568_CRU_GPLL_CON(0)); 3498 case RK3568_PLL_NPLL: 3499 return rk3328_get_pll(sc, RK3568_CRU_NPLL_CON(0)); 3500 case RK3568_PLL_VPLL: 3501 return rk3328_get_pll(sc, RK3568_CRU_VPLL_CON(0)); 3502 case RK3568_SCLK_GMAC0_DIV_50: 3503 idx = RK3568_SCLK_GMAC0; 3504 return rk3568_get_frequency(sc, &idx) / 50; 3505 case RK3568_SCLK_GMAC0_DIV_5: 3506 idx = RK3568_SCLK_GMAC0; 3507 return rk3568_get_frequency(sc, &idx) / 5; 3508 case RK3568_SCLK_GMAC0_DIV_20: 3509 idx = RK3568_SCLK_GMAC0; 3510 return rk3568_get_frequency(sc, &idx) / 20; 3511 case RK3568_SCLK_GMAC0_DIV_2: 3512 idx = RK3568_SCLK_GMAC0; 3513 return rk3568_get_frequency(sc, &idx) / 2; 3514 case RK3568_SCLK_GMAC1_DIV_50: 3515 idx = RK3568_SCLK_GMAC1; 3516 return rk3568_get_frequency(sc, &idx) / 50; 3517 case RK3568_SCLK_GMAC1_DIV_5: 3518 idx = RK3568_SCLK_GMAC1; 3519 return rk3568_get_frequency(sc, &idx) / 5; 3520 case RK3568_SCLK_GMAC1_DIV_20: 3521 idx = RK3568_SCLK_GMAC1; 3522 return rk3568_get_frequency(sc, &idx) / 20; 3523 case RK3568_SCLK_GMAC1_DIV_2: 3524 idx = RK3568_SCLK_GMAC1; 3525 return rk3568_get_frequency(sc, &idx) / 2; 3526 case RK3568_CLK_OSC0_DIV_375K: 3527 idx = RK3568_CLK_OSC0_DIV_750K; 3528 return rk3568_get_frequency(sc, &idx) / 2; 3529 case RK3568_GMAC0_CLKIN: 3530 return rkclock_external_frequency("gmac0_clkin"); 3531 case RK3568_GMAC1_CLKIN: 3532 return rkclock_external_frequency("gmac1_clkin"); 3533 case RK3568_XIN24M: 3534 return 24000000; 3535 default: 3536 break; 3537 } 3538 3539 return rkclock_get_frequency(sc, idx); 3540 } 3541 3542 int 3543 rk3568_set_frequency(void *cookie, uint32_t *cells, uint32_t freq) 3544 { 3545 struct rkclock_softc *sc = cookie; 3546 uint32_t idx = cells[0]; 3547 3548 switch (idx) { 3549 case RK3568_PLL_GPLL: 3550 return rk3568_set_pll(sc, RK3568_CRU_GPLL_CON(0), freq); 3551 default: 3552 break; 3553 } 3554 3555 return rkclock_set_frequency(sc, idx, freq); 3556 } 3557 3558 int 3559 rk3568_set_parent(void *cookie, uint32_t *cells, uint32_t *pcells) 3560 { 3561 struct rkclock_softc *sc = cookie; 3562 char buf[64] = {}; 3563 int len, node; 3564 3565 if (pcells[0] != sc->sc_phandle) { 3566 node = OF_getnodebyphandle(pcells[0]); 3567 if (node == 0) 3568 return -1; 3569 len = OF_getproplen(node, "clock-output-names"); 3570 if (len <= 0 || len > sizeof(buf)) 3571 return -1; 3572 OF_getprop(node, "clock-output-names", buf, sizeof(buf)); 3573 3574 if (strcmp(buf, "gmac0_clkin") == 0) { 3575 return rkclock_set_parent(sc, cells[0], 3576 RK3568_GMAC0_CLKIN); 3577 } 3578 if (strcmp(buf, "gmac1_clkin") == 0) { 3579 return rkclock_set_parent(sc, cells[0], 3580 RK3568_GMAC1_CLKIN); 3581 } 3582 3583 printf("%s: 0x%08x 0x%08x\n", __func__, cells[0], pcells[0]); 3584 return -1; 3585 } 3586 3587 return rkclock_set_parent(sc, cells[0], pcells[1]); 3588 } 3589 3590 void 3591 rk3568_enable(void *cookie, uint32_t *cells, int on) 3592 { 3593 uint32_t idx = cells[0]; 3594 3595 /* All clocks are enabled upon hardware reset. */ 3596 if (!on) { 3597 printf("%s: 0x%08x\n", __func__, idx); 3598 return; 3599 } 3600 } 3601 3602 void 3603 rk3568_reset(void *cookie, uint32_t *cells, int on) 3604 { 3605 struct rkclock_softc *sc = cookie; 3606 uint32_t idx = cells[0]; 3607 uint32_t mask = (1 << (idx % 16)); 3608 3609 HWRITE4(sc, RK3568_CRU_SOFTRST_CON(idx / 16), 3610 mask << 16 | (on ? mask : 0)); 3611 } 3612 3613 /* PMUCRU */ 3614 3615 const struct rkclock rk3568_pmu_clocks[] = { 3616 { 3617 RK3568_CLK_RTC_32K, RK3568_PMUCRU_CLKSEL_CON(0), 3618 SEL(7, 6), 0, 3619 { 0, RK3568_XIN32K, RK3568_CLK_RTC32K_FRAC }, 3620 SET_PARENT 3621 }, 3622 { 3623 RK3568_CLK_I2C0, RK3568_PMUCRU_CLKSEL_CON(3), 3624 0, DIV(15, 7), 3625 { RK3568_CLK_PDPMU } 3626 }, 3627 { 3628 RK3568_SCLK_UART0, RK3568_PMUCRU_CLKSEL_CON(4), 3629 SEL(11, 10), 0, 3630 { 0, 0, RK3568_XIN24M } 3631 }, 3632 { 3633 RK3568_CLK_PCIEPHY0_OSC0, 0, 0, 0, 3634 { RK3568_XIN24M } 3635 }, 3636 { 3637 RK3568_CLK_PCIEPHY0_DIV, RK3568_PMUCRU_CLKSEL_CON(9), 3638 0, DIV(2, 0), 3639 { RK3568_PPLL_PH0 } 3640 }, 3641 { 3642 RK3568_CLK_PCIEPHY0_REF, RK3568_PMUCRU_CLKSEL_CON(9), 3643 SEL(3, 3), 0, 3644 { RK3568_CLK_PCIEPHY0_OSC0, RK3568_CLK_PCIEPHY0_DIV }, 3645 SET_PARENT 3646 }, 3647 { 3648 RK3568_CLK_PCIEPHY1_OSC0, 0, 0, 0, 3649 { RK3568_XIN24M } 3650 }, 3651 { 3652 RK3568_CLK_PCIEPHY1_DIV, RK3568_PMUCRU_CLKSEL_CON(9), 3653 0, DIV(6, 4), 3654 { RK3568_PPLL_PH0 } 3655 }, 3656 { 3657 RK3568_CLK_PCIEPHY1_REF, RK3568_PMUCRU_CLKSEL_CON(9), 3658 SEL(7, 7), 0, 3659 { RK3568_CLK_PCIEPHY1_OSC0, RK3568_CLK_PCIEPHY1_DIV }, 3660 SET_PARENT 3661 }, 3662 { 3663 RK3568_CLK_PCIEPHY2_OSC0, 0, 0, 0, 3664 { RK3568_XIN24M } 3665 }, 3666 { 3667 RK3568_CLK_PCIEPHY2_DIV, RK3568_PMUCRU_CLKSEL_CON(9), 3668 0, DIV(10, 8), 3669 { RK3568_PPLL_PH0 } 3670 }, 3671 { 3672 RK3568_CLK_PCIEPHY2_REF, RK3568_PMUCRU_CLKSEL_CON(9), 3673 SEL(11, 11), 0, 3674 { RK3568_CLK_PCIEPHY2_OSC0, RK3568_CLK_PCIEPHY2_DIV }, 3675 SET_PARENT 3676 }, 3677 { 3678 RK3568_CLK_PDPMU, RK3568_PMUCRU_CLKSEL_CON(2), 3679 SEL(15, 15), 0, 3680 { RK3568_PLL_PPLL, 0 } 3681 }, 3682 { 3683 /* Sentinel */ 3684 } 3685 }; 3686 3687 void 3688 rk3568_pmu_init(struct rkclock_softc *sc) 3689 { 3690 int i; 3691 3692 /* The code below assumes all clocks are enabled. Check this!. */ 3693 for (i = 0; i <= 2; i++) { 3694 if (HREAD4(sc, RK3568_PMUCRU_GATE_CON(i)) != 0x00000000) { 3695 printf("CRU_GATE_CON%d: 0x%08x\n", i, 3696 HREAD4(sc, RK3568_CRU_GATE_CON(i))); 3697 } 3698 } 3699 3700 sc->sc_clocks = rk3568_pmu_clocks; 3701 } 3702 3703 int 3704 rk3568_pmu_set_pll(struct rkclock_softc *sc, bus_size_t base, uint32_t freq) 3705 { 3706 uint32_t fbdiv, postdiv1, postdiv2, refdiv; 3707 int mode_shift = -1; 3708 3709 switch (base) { 3710 case RK3568_PMUCRU_PPLL_CON(0): 3711 mode_shift = 0; 3712 break; 3713 case RK3568_PMUCRU_HPLL_CON(0): 3714 mode_shift = 2; 3715 break; 3716 } 3717 KASSERT(mode_shift != -1); 3718 3719 /* 3720 * It is not clear whether all combinations of the clock 3721 * dividers result in a stable clock. Therefore this function 3722 * only supports a limited set of PLL clock rates. 3723 */ 3724 switch (freq) { 3725 case 200000000U: 3726 postdiv1 = 3; postdiv2 = 4; refdiv = 1; 3727 break; 3728 default: 3729 printf("%s: %u Hz\n", __func__, freq); 3730 return -1; 3731 } 3732 3733 /* Calculate feedback divider. */ 3734 fbdiv = freq * postdiv1 * postdiv2 * refdiv / 24000000; 3735 3736 /* 3737 * Select slow mode to guarantee a stable clock while we're 3738 * adjusting the PLL. 3739 */ 3740 HWRITE4(sc, RK3568_PMUCRU_MODE_CON, 3741 (RK3328_CRU_CRU_MODE_MASK << 16 | 3742 RK3328_CRU_CRU_MODE_SLOW) << mode_shift); 3743 3744 /* Set PLL rate. */ 3745 HWRITE4(sc, base + 0x0000, 3746 RK3328_CRU_PLL_POSTDIV1_MASK << 16 | 3747 postdiv1 << RK3328_CRU_PLL_POSTDIV1_SHIFT | 3748 RK3328_CRU_PLL_FBDIV_MASK << 16 | 3749 fbdiv << RK3328_CRU_PLL_FBDIV_SHIFT); 3750 HWRITE4(sc, base + 0x0004, 3751 RK3328_CRU_PLL_DSMPD << 16 | RK3328_CRU_PLL_DSMPD | 3752 RK3328_CRU_PLL_POSTDIV2_MASK << 16 | 3753 postdiv2 << RK3328_CRU_PLL_POSTDIV2_SHIFT | 3754 RK3328_CRU_PLL_REFDIV_MASK << 16 | 3755 refdiv << RK3328_CRU_PLL_REFDIV_SHIFT); 3756 3757 /* Wait for PLL to stabilize. */ 3758 while ((HREAD4(sc, base + 0x0004) & RK3328_CRU_PLL_PLL_LOCK) == 0) 3759 delay(10); 3760 3761 /* Switch back to normal mode. */ 3762 HWRITE4(sc, RK3568_PMUCRU_MODE_CON, 3763 (RK3328_CRU_CRU_MODE_MASK << 16 | 3764 RK3328_CRU_CRU_MODE_NORMAL) << mode_shift); 3765 3766 return 0; 3767 } 3768 3769 uint32_t 3770 rk3568_pmu_get_frequency(void *cookie, uint32_t *cells) 3771 { 3772 struct rkclock_softc *sc = cookie; 3773 uint32_t idx = cells[0]; 3774 3775 switch (idx) { 3776 case RK3568_PLL_PPLL: 3777 return rk3328_get_pll(sc, RK3568_PMUCRU_PPLL_CON(0)); 3778 case RK3568_PLL_HPLL: 3779 return rk3328_get_pll(sc, RK3568_PMUCRU_HPLL_CON(0)); 3780 case RK3568_CLK_RTC32K_FRAC: 3781 return rk3399_get_frac(sc, RK3568_XIN24M, 3782 RK3568_PMUCRU_CLKSEL_CON(1)); 3783 case RK3568_PPLL_PH0: 3784 idx = RK3568_PLL_PPLL; 3785 return rk3568_get_frequency(sc, &idx) / 2; 3786 case RK3568_XIN32K: 3787 return 32768; 3788 case RK3568_XIN24M: 3789 return 24000000; 3790 default: 3791 break; 3792 } 3793 3794 return rkclock_get_frequency(sc, idx); 3795 } 3796 3797 int 3798 rk3568_pmu_set_frequency(void *cookie, uint32_t *cells, uint32_t freq) 3799 { 3800 struct rkclock_softc *sc = cookie; 3801 uint32_t idx = cells[0]; 3802 3803 switch (idx) { 3804 case RK3568_PLL_PPLL: 3805 return rk3568_pmu_set_pll(sc, RK3568_PMUCRU_PPLL_CON(0), freq); 3806 case RK3568_PLL_HPLL: 3807 return rk3568_pmu_set_pll(sc, RK3568_PMUCRU_HPLL_CON(0), freq); 3808 case RK3568_CLK_RTC32K_FRAC: 3809 return rk3399_set_frac(sc, RK3568_XIN24M, 3810 RK3568_PMUCRU_CLKSEL_CON(1), freq); 3811 default: 3812 break; 3813 } 3814 3815 return rkclock_set_frequency(sc, idx, freq); 3816 } 3817 3818 void 3819 rk3568_pmu_enable(void *cookie, uint32_t *cells, int on) 3820 { 3821 uint32_t idx = cells[0]; 3822 3823 switch (idx) { 3824 case RK3568_CLK_USBPHY0_REF: 3825 case RK3568_CLK_USBPHY1_REF: 3826 case RK3568_CLK_PCIEPHY0_REF: 3827 case RK3568_CLK_PCIEPHY1_REF: 3828 case RK3568_CLK_PCIEPHY2_REF: 3829 case RK3568_CLK_PCIE30PHY_REF_M: 3830 case RK3568_CLK_PCIE30PHY_REF_N: 3831 case RK3568_CLK_I2C0: 3832 case RK3568_SCLK_UART0: 3833 case RK3568_PCLK_I2C0: 3834 /* Enabled by default. */ 3835 break; 3836 default: 3837 printf("%s: 0x%08x\n", __func__, idx); 3838 break; 3839 } 3840 } 3841 3842 void 3843 rk3568_pmu_reset(void *cookie, uint32_t *cells, int on) 3844 { 3845 uint32_t idx = cells[0]; 3846 3847 printf("%s: 0x%08x\n", __func__, idx); 3848 } 3849 3850 /* 3851 * Rockchip RK3588 3852 */ 3853 3854 const struct rkclock rk3588_clocks[] = { 3855 { 3856 RK3588_ACLK_BUS_ROOT, RK3588_CRU_CLKSEL_CON(38), 3857 SEL(5, 5), DIV(4, 0), 3858 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 3859 }, 3860 { 3861 RK3588_CLK_I2C1, RK3588_CRU_CLKSEL_CON(38), 3862 SEL(6, 6), 0, 3863 { RK3588_CLK_200M_SRC , RK3588_CLK_100M_SRC }, 3864 }, 3865 { 3866 RK3588_CLK_I2C2, RK3588_CRU_CLKSEL_CON(38), 3867 SEL(7, 7), 0, 3868 { RK3588_CLK_200M_SRC , RK3588_CLK_100M_SRC }, 3869 }, 3870 { 3871 RK3588_CLK_I2C3, RK3588_CRU_CLKSEL_CON(38), 3872 SEL(8, 8), 0, 3873 { RK3588_CLK_200M_SRC , RK3588_CLK_100M_SRC }, 3874 }, 3875 { 3876 RK3588_CLK_I2C4, RK3588_CRU_CLKSEL_CON(38), 3877 SEL(9, 9), 0, 3878 { RK3588_CLK_200M_SRC , RK3588_CLK_100M_SRC }, 3879 }, 3880 { 3881 RK3588_CLK_I2C5, RK3588_CRU_CLKSEL_CON(38), 3882 SEL(10, 10), 0, 3883 { RK3588_CLK_200M_SRC , RK3588_CLK_100M_SRC }, 3884 }, 3885 { 3886 RK3588_CLK_I2C6, RK3588_CRU_CLKSEL_CON(38), 3887 SEL(11, 11), 0, 3888 { RK3588_CLK_200M_SRC , RK3588_CLK_100M_SRC }, 3889 }, 3890 { 3891 RK3588_CLK_I2C7, RK3588_CRU_CLKSEL_CON(38), 3892 SEL(12, 12), 0, 3893 { RK3588_CLK_200M_SRC , RK3588_CLK_100M_SRC }, 3894 }, 3895 { 3896 RK3588_CLK_I2C8, RK3588_CRU_CLKSEL_CON(38), 3897 SEL(13, 13), 0, 3898 { RK3588_CLK_200M_SRC , RK3588_CLK_100M_SRC }, 3899 }, 3900 { 3901 RK3588_CLK_UART1_SRC, RK3588_CRU_CLKSEL_CON(41), 3902 SEL(14, 14), DIV(13, 9), 3903 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 3904 }, 3905 { 3906 RK3588_CLK_UART1, RK3588_CRU_CLKSEL_CON(43), 3907 SEL(1, 0), 0, 3908 { RK3588_CLK_UART1_SRC, RK3588_CLK_UART1_FRAC, RK3588_XIN24M } 3909 }, 3910 { 3911 RK3588_SCLK_UART1, 0, 0, 0, 3912 { RK3588_CLK_UART1 } 3913 }, 3914 { 3915 RK3588_CLK_UART2_SRC, RK3588_CRU_CLKSEL_CON(43), 3916 SEL(7, 7), DIV(6, 2), 3917 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 3918 }, 3919 { 3920 RK3588_CLK_UART2, RK3588_CRU_CLKSEL_CON(45), 3921 SEL(1, 0), 0, 3922 { RK3588_CLK_UART2_SRC, RK3588_CLK_UART2_FRAC, RK3588_XIN24M } 3923 }, 3924 { 3925 RK3588_SCLK_UART2, 0, 0, 0, 3926 { RK3588_CLK_UART2 } 3927 }, 3928 { 3929 RK3588_CLK_UART3_SRC, RK3588_CRU_CLKSEL_CON(45), 3930 SEL(7, 7), DIV(6, 2), 3931 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 3932 }, 3933 { 3934 RK3588_CLK_UART3, RK3588_CRU_CLKSEL_CON(47), 3935 SEL(1, 0), 0, 3936 { RK3588_CLK_UART3_SRC, RK3588_CLK_UART3_FRAC, RK3588_XIN24M } 3937 }, 3938 { 3939 RK3588_SCLK_UART3, 0, 0, 0, 3940 { RK3588_CLK_UART3 } 3941 }, 3942 { 3943 RK3588_CLK_UART4_SRC, RK3588_CRU_CLKSEL_CON(47), 3944 SEL(7, 7), DIV(6, 2), 3945 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 3946 }, 3947 { 3948 RK3588_CLK_UART4, RK3588_CRU_CLKSEL_CON(49), 3949 SEL(1, 0), 0, 3950 { RK3588_CLK_UART4_SRC, RK3588_CLK_UART4_FRAC, RK3588_XIN24M } 3951 }, 3952 { 3953 RK3588_SCLK_UART4, 0, 0, 0, 3954 { RK3588_CLK_UART4 } 3955 }, 3956 { 3957 RK3588_CLK_UART5_SRC, RK3588_CRU_CLKSEL_CON(49), 3958 SEL(7, 7), DIV(6, 2), 3959 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 3960 }, 3961 { 3962 RK3588_CLK_UART5, RK3588_CRU_CLKSEL_CON(51), 3963 SEL(1, 0), 0, 3964 { RK3588_CLK_UART5_SRC, RK3588_CLK_UART5_FRAC, RK3588_XIN24M } 3965 }, 3966 { 3967 RK3588_SCLK_UART5, 0, 0, 0, 3968 { RK3588_CLK_UART5 } 3969 }, 3970 { 3971 RK3588_CLK_UART6_SRC, RK3588_CRU_CLKSEL_CON(51), 3972 SEL(7, 7), DIV(6, 2), 3973 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 3974 }, 3975 { 3976 RK3588_CLK_UART6, RK3588_CRU_CLKSEL_CON(53), 3977 SEL(1, 0), 0, 3978 { RK3588_CLK_UART6_SRC, RK3588_CLK_UART6_FRAC, RK3588_XIN24M } 3979 }, 3980 { 3981 RK3588_SCLK_UART6, 0, 0, 0, 3982 { RK3588_CLK_UART6 } 3983 }, 3984 { 3985 RK3588_CLK_UART7_SRC, RK3588_CRU_CLKSEL_CON(53), 3986 SEL(7, 7), DIV(6, 2), 3987 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 3988 }, 3989 { 3990 RK3588_CLK_UART7, RK3588_CRU_CLKSEL_CON(55), 3991 SEL(1, 0), 0, 3992 { RK3588_CLK_UART7_SRC, RK3588_CLK_UART7_FRAC, RK3588_XIN24M } 3993 }, 3994 { 3995 RK3588_SCLK_UART7, 0, 0, 0, 3996 { RK3588_CLK_UART7 } 3997 }, 3998 { 3999 RK3588_CLK_UART8_SRC, RK3588_CRU_CLKSEL_CON(55), 4000 SEL(7, 7), DIV(6, 2), 4001 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 4002 }, 4003 { 4004 RK3588_CLK_UART8, RK3588_CRU_CLKSEL_CON(57), 4005 SEL(1, 0), 0, 4006 { RK3588_CLK_UART8_SRC, RK3588_CLK_UART8_FRAC, RK3588_XIN24M } 4007 }, 4008 { 4009 RK3588_SCLK_UART8, 0, 0, 0, 4010 { RK3588_CLK_UART8 } 4011 }, 4012 { 4013 RK3588_CLK_UART9_SRC, RK3588_CRU_CLKSEL_CON(57), 4014 SEL(7, 7), DIV(6, 2), 4015 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 4016 }, 4017 { 4018 RK3588_CLK_UART9, RK3588_CRU_CLKSEL_CON(59), 4019 SEL(1, 0), 0, 4020 { RK3588_CLK_UART9_SRC, RK3588_CLK_UART9_FRAC, RK3588_XIN24M } 4021 }, 4022 { 4023 RK3588_SCLK_UART9, 0, 0, 0, 4024 { RK3588_CLK_UART9 } 4025 }, 4026 { 4027 RK3588_ACLK_CENTER_ROOT, RK3588_CRU_CLKSEL_CON(165), 4028 SEL(1, 0), 0, 4029 { RK3588_CLK_700M_SRC, RK3588_CLK_400M_SRC, 4030 RK3588_CLK_200M_SRC, RK3588_XIN24M } 4031 }, 4032 { 4033 RK3588_ACLK_CENTER_LOW_ROOT, RK3588_CRU_CLKSEL_CON(165), 4034 SEL(3, 2), 0, 4035 { RK3588_CLK_500M_SRC, RK3588_CLK_250M_SRC, 4036 RK3588_CLK_100M_SRC, RK3588_XIN24M } 4037 }, 4038 { 4039 RK3588_HCLK_CENTER_ROOT, RK3588_CRU_CLKSEL_CON(165), 4040 SEL(5, 4), 0, 4041 { RK3588_CLK_400M_SRC, RK3588_CLK_200M_SRC, 4042 RK3588_CLK_100M_SRC, RK3588_XIN24M } 4043 }, 4044 { 4045 RK3588_CLK_50M_SRC, RK3588_CRU_CLKSEL_CON(0), 4046 SEL(5, 5), DIV(4, 0), 4047 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 4048 }, 4049 { 4050 RK3588_CLK_100M_SRC, RK3588_CRU_CLKSEL_CON(0), 4051 SEL(11, 11), DIV(10, 6), 4052 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 4053 }, 4054 { 4055 RK3588_CLK_150M_SRC, RK3588_CRU_CLKSEL_CON(1), 4056 SEL(5, 5), DIV(4, 0), 4057 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 4058 }, 4059 { 4060 RK3588_CLK_200M_SRC, RK3588_CRU_CLKSEL_CON(1), 4061 SEL(11, 11), DIV(10, 6), 4062 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 4063 }, 4064 { 4065 RK3588_CLK_250M_SRC, RK3588_CRU_CLKSEL_CON(2), 4066 SEL(5, 5), DIV(4, 0), 4067 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 4068 }, 4069 { 4070 RK3588_CLK_400M_SRC, RK3588_CRU_CLKSEL_CON(3), 4071 SEL(11, 11), DIV(10, 6), 4072 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 4073 }, 4074 { 4075 RK3588_CLK_500M_SRC, RK3588_CRU_CLKSEL_CON(4), 4076 SEL(11, 11), DIV(10, 6), 4077 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 4078 }, 4079 { 4080 RK3588_CLK_700M_SRC, RK3588_CRU_CLKSEL_CON(6), 4081 SEL(5, 5), DIV(4, 0), 4082 { RK3588_PLL_GPLL, RK3588_PLL_SPLL } 4083 }, 4084 { 4085 RK3588_ACLK_TOP_ROOT, RK3588_CRU_CLKSEL_CON(8), 4086 SEL(6, 5), 0, 4087 { RK3588_PLL_GPLL, RK3588_PLL_CPLL, RK3588_PLL_AUPLL } 4088 }, 4089 { 4090 RK3588_PCLK_TOP_ROOT, RK3588_CRU_CLKSEL_CON(8), 4091 SEL(8, 7), 0, 4092 { RK3588_CLK_100M_SRC, RK3588_CLK_50M_SRC, RK3588_XIN24M } 4093 }, 4094 { 4095 RK3588_ACLK_LOW_TOP_ROOT, RK3588_CRU_CLKSEL_CON(8), 4096 SEL(14, 14), DIV(13, 9), 4097 { RK3588_PLL_GPLL, RK3588_PLL_CPLL } 4098 }, 4099 { 4100 RK3588_CLK_GPU_SRC, RK3588_CRU_CLKSEL_CON(158), 4101 SEL(7, 5), DIV(4, 0), 4102 { RK3588_PLL_GPLL, RK3588_PLL_CPLL, RK3588_PLL_AUPLL, 4103 RK3588_PLL_NPLL, RK3588_PLL_SPLL } 4104 }, 4105 { 4106 RK3588_CLK_GPU, 0, 0, 0, 4107 { RK3588_CLK_GPU_SRC }, 4108 SET_PARENT 4109 }, 4110 { 4111 RK3588_CCLK_SRC_SDIO, RK3588_CRU_CLKSEL_CON(172), 4112 SEL(9, 8), DIV(7, 2), 4113 { RK3588_PLL_GPLL, RK3588_PLL_CPLL, RK3588_XIN24M } 4114 }, 4115 { 4116 RK3588_ACLK_VOP_ROOT, RK3588_CRU_CLKSEL_CON(110), 4117 SEL(7, 5), DIV(4, 0), 4118 { RK3588_PLL_GPLL, RK3588_PLL_CPLL, RK3588_PLL_AUPLL, 4119 RK3588_PLL_NPLL, RK3588_PLL_SPLL } 4120 }, 4121 { 4122 RK3588_ACLK_VOP, 0, 0, 0, 4123 { RK3588_ACLK_VOP_SUB_SRC }, 4124 SET_PARENT 4125 }, 4126 { 4127 RK3588_ACLK_VOP_SUB_SRC, RK3588_CRU_CLKSEL_CON(115), 4128 SEL(9, 9), 0, 4129 { RK3588_ACLK_VOP_ROOT, 0 /* RK3588_ACLK_VOP_DIV2_SRC */ }, 4130 SET_PARENT 4131 }, 4132 { 4133 RK3588_CLK_I2C0, RK3588_CRU_CLKSEL_CON(3), 4134 SEL(6, 6), 0, 4135 { RK3588_CLK_PMU1_200M_SRC, RK3588_CLK_PMU1_100M_SRC }, 4136 }, 4137 { 4138 RK3588_CLK_PMU1_50M_SRC, RK3588_PMUCRU_CLKSEL_CON(0), 4139 0, DIV(3, 0), 4140 { RK3588_CLK_PMU1_400M_SRC } 4141 }, 4142 { 4143 RK3588_CLK_PMU1_100M_SRC, RK3588_PMUCRU_CLKSEL_CON(0), 4144 0, DIV(6, 4), 4145 { RK3588_CLK_PMU1_400M_SRC } 4146 }, 4147 { 4148 RK3588_CLK_PMU1_200M_SRC, RK3588_PMUCRU_CLKSEL_CON(0), 4149 0, DIV(9, 7), 4150 { RK3588_CLK_PMU1_400M_SRC } 4151 }, 4152 { 4153 RK3588_CLK_PMU1_400M_SRC, RK3588_PMUCRU_CLKSEL_CON(1), 4154 SEL(5, 5), DIV(4, 0), 4155 { RK3588_CLK_400M_SRC, RK3588_XIN24M } 4156 }, 4157 { 4158 RK3588_PCLK_PMU1_ROOT, RK3588_PMUCRU_CLKSEL_CON(1), 4159 SEL(9, 8), 0, 4160 { RK3588_CLK_PMU1_100M_SRC, RK3588_CLK_PMU1_50M_SRC, 4161 RK3588_XIN24M } 4162 }, 4163 { 4164 RK3588_PCLK_PMU0_ROOT, 0, 0, 0, 4165 { RK3588_PCLK_PMU1_ROOT }, 4166 SET_PARENT 4167 }, 4168 { 4169 RK3588_HCLK_PMU_CM0_ROOT, RK3588_PMUCRU_CLKSEL_CON(1), 4170 SEL(11, 10), 0, 4171 { RK3588_CLK_PMU1_400M_SRC, RK3588_CLK_PMU1_200M_SRC, 4172 RK3588_CLK_PMU1_100M_SRC, RK3588_XIN24M } 4173 }, 4174 { 4175 RK3588_CLK_PMU1PWM, RK3588_PMUCRU_CLKSEL_CON(2), 4176 SEL(10, 9), 0, 4177 { RK3588_CLK_PMU1_100M_SRC, RK3588_CLK_PMU1_50M_SRC, 4178 RK3588_XIN24M } 4179 }, 4180 { 4181 RK3588_CLK_UART0_SRC, RK3588_PMUCRU_CLKSEL_CON(3), 4182 0, DIV(11, 7), 4183 { RK3588_PLL_CPLL } 4184 }, 4185 { 4186 RK3588_CLK_UART0, RK3588_PMUCRU_CLKSEL_CON(5), 4187 SEL(1, 0), 0, 4188 { RK3588_CLK_UART0_SRC, RK3588_CLK_UART0_FRAC, RK3588_XIN24M } 4189 }, 4190 { 4191 RK3588_SCLK_UART0, 0, 0, 0, 4192 { RK3588_CLK_UART0 } 4193 }, 4194 { 4195 RK3588_CLK_REF_PIPE_PHY0_OSC_SRC, 0, 0, 0, 4196 { RK3588_XIN24M } 4197 }, 4198 { 4199 RK3588_CLK_REF_PIPE_PHY1_OSC_SRC, 0, 0, 0, 4200 { RK3588_XIN24M } 4201 }, 4202 { 4203 RK3588_CLK_REF_PIPE_PHY2_OSC_SRC, 0, 0, 0, 4204 { RK3588_XIN24M } 4205 }, 4206 { 4207 RK3588_CLK_REF_PIPE_PHY0_PLL_SRC, RK3588_CRU_CLKSEL_CON(176), 4208 0, DIV(5, 0), 4209 { RK3588_PLL_PPLL } 4210 }, 4211 { 4212 RK3588_CLK_REF_PIPE_PHY1_PLL_SRC, RK3588_CRU_CLKSEL_CON(176), 4213 0, DIV(11, 6), 4214 { RK3588_PLL_PPLL } 4215 }, 4216 { 4217 RK3588_CLK_REF_PIPE_PHY2_PLL_SRC, RK3588_CRU_CLKSEL_CON(177), 4218 0, DIV(5, 0), 4219 { RK3588_PLL_PPLL } 4220 }, 4221 { 4222 RK3588_CLK_REF_PIPE_PHY0, RK3588_CRU_CLKSEL_CON(177), 4223 SEL(6, 6), 0, 4224 { RK3588_CLK_REF_PIPE_PHY0_OSC_SRC, 4225 RK3588_CLK_REF_PIPE_PHY0_PLL_SRC }, 4226 }, 4227 { 4228 RK3588_CLK_REF_PIPE_PHY1, RK3588_CRU_CLKSEL_CON(177), 4229 SEL(7, 7), 0, 4230 { RK3588_CLK_REF_PIPE_PHY1_OSC_SRC, 4231 RK3588_CLK_REF_PIPE_PHY1_PLL_SRC }, 4232 }, 4233 { 4234 RK3588_CLK_REF_PIPE_PHY2, RK3588_CRU_CLKSEL_CON(177), 4235 SEL(8, 8), 0, 4236 { RK3588_CLK_REF_PIPE_PHY2_OSC_SRC, 4237 RK3588_CLK_REF_PIPE_PHY2_PLL_SRC }, 4238 }, 4239 { 4240 /* Sentinel */ 4241 } 4242 }; 4243 4244 /* Certain test clocks are disabled. */ 4245 const uint32_t rk3588_gates[78] = { 4246 [2] = 0x00000050, 4247 [22] = 0x00000200, 4248 [25] = 0x00000200, 4249 [29] = 0x00000004, 4250 [66] = 0x00000004, 4251 }; 4252 4253 void 4254 rk3588_init(struct rkclock_softc *sc) 4255 { 4256 int i; 4257 4258 /* The code below assumes all clocks are enabled. Check this!. */ 4259 for (i = 0; i < nitems(rk3588_gates); i++) { 4260 if (HREAD4(sc, RK3588_CRU_GATE_CON(i)) != rk3588_gates[i]) { 4261 printf("CRU_GATE_CON%d: 0x%08x\n", i, 4262 HREAD4(sc, RK3588_CRU_GATE_CON(i))); 4263 } 4264 } 4265 4266 sc->sc_clocks = rk3588_clocks; 4267 } 4268 4269 int 4270 rk3588_set_pll(struct rkclock_softc *sc, bus_size_t base, uint32_t freq) 4271 { 4272 uint32_t p, m, s, k; 4273 int mode_shift = -1; 4274 4275 switch (base) { 4276 case RK3588_CRU_AUPLL_CON(0): 4277 mode_shift = 6; 4278 break; 4279 case RK3588_CRU_GPLL_CON(0): 4280 mode_shift = 2; 4281 break; 4282 case RK3588_CRU_NPLL_CON(0): 4283 mode_shift = 0; 4284 break; 4285 case RK3588_PHPTOPCRU_PPLL_CON(0): 4286 mode_shift = 10; 4287 break; 4288 } 4289 KASSERT(mode_shift != -1); 4290 4291 /* 4292 * It is not clear whether all combinations of the clock 4293 * dividers result in a stable clock. Therefore this function 4294 * only supports a limited set of PLL clock rates. 4295 */ 4296 switch (freq) { 4297 case 1188000000U: 4298 p = 2; m = 198; s = 1; k = 0; 4299 break; 4300 case 1100000000U: 4301 p = 3; m = 550; s = 2; k = 0; 4302 break; 4303 case 850000000U: 4304 p = 3; m = 425; s = 2; k = 0; 4305 break; 4306 case 786432000U: 4307 p = 2; m = 262; s = 2; k = 9437; 4308 break; 4309 case 100000000U: 4310 p = 3; m = 400; s = 5; k = 0; 4311 break; 4312 default: 4313 printf("%s: %u Hz\n", __func__, freq); 4314 return -1; 4315 } 4316 4317 /* 4318 * Select slow mode to guarantee a stable clock while we're 4319 * adjusting the PLL. 4320 */ 4321 HWRITE4(sc, RK3588_CRU_MODE_CON, 4322 (RK3588_CRU_MODE_MASK << 16 |RK3588_CRU_MODE_SLOW) << mode_shift); 4323 4324 /* Power down PLL. */ 4325 HWRITE4(sc, base + 0x0004, 4326 RK3588_CRU_PLL_RESETB << 16 | RK3588_CRU_PLL_RESETB); 4327 4328 /* Set PLL rate. */ 4329 HWRITE4(sc, base + 0x0000, 4330 RK3588_CRU_PLL_M_MASK << 16 | m << RK3588_CRU_PLL_M_SHIFT); 4331 HWRITE4(sc, base + 0x0004, 4332 RK3588_CRU_PLL_S_MASK << 16 | s << RK3588_CRU_PLL_S_SHIFT | 4333 RK3588_CRU_PLL_P_MASK << 16 | p << RK3588_CRU_PLL_P_SHIFT); 4334 HWRITE4(sc, base + 0x0008, 4335 RK3588_CRU_PLL_K_MASK << 16 | k << RK3588_CRU_PLL_K_SHIFT); 4336 4337 /* Power up PLL. */ 4338 HWRITE4(sc, base + 0x0004, RK3588_CRU_PLL_RESETB << 16); 4339 4340 /* Wait for PLL to stabilize. */ 4341 while ((HREAD4(sc, base + 0x0018) & RK3588_CRU_PLL_PLL_LOCK) == 0) 4342 delay(10); 4343 4344 /* Switch back to normal mode. */ 4345 HWRITE4(sc, RK3588_CRU_MODE_CON, 4346 (RK3588_CRU_MODE_MASK << 16 | RK3588_CRU_MODE_NORMAL) << mode_shift); 4347 4348 return 0; 4349 } 4350 4351 uint32_t 4352 rk3588_get_pll(struct rkclock_softc *sc, bus_size_t base) 4353 { 4354 uint64_t freq, frac; 4355 uint32_t k, m, p, s; 4356 uint32_t reg; 4357 4358 reg = HREAD4(sc, base); 4359 m = (reg & RK3588_CRU_PLL_M_MASK) >> RK3588_CRU_PLL_M_SHIFT; 4360 reg = HREAD4(sc, base + 4); 4361 p = (reg & RK3588_CRU_PLL_P_MASK) >> RK3588_CRU_PLL_P_SHIFT; 4362 s = (reg & RK3588_CRU_PLL_S_MASK) >> RK3588_CRU_PLL_S_SHIFT; 4363 reg = HREAD4(sc, base + 8); 4364 k = (reg & RK3588_CRU_PLL_K_MASK) >> RK3588_CRU_PLL_K_SHIFT; 4365 4366 freq = (24000000ULL * m) / p; 4367 if (k) { 4368 frac = ((24000000ULL * k) / (p * 65535)); 4369 freq += frac; 4370 } 4371 4372 return freq >> s; 4373 } 4374 4375 uint32_t 4376 rk3588_get_frequency(void *cookie, uint32_t *cells) 4377 { 4378 struct rkclock_softc *sc = cookie; 4379 uint32_t idx = cells[0]; 4380 uint32_t freq; 4381 4382 switch (idx) { 4383 case RK3588_PLL_AUPLL: 4384 return rk3588_get_pll(sc, RK3588_CRU_AUPLL_CON(0)); 4385 case RK3588_PLL_CPLL: 4386 return rk3588_get_pll(sc, RK3588_CRU_CPLL_CON(0)); 4387 case RK3588_PLL_GPLL: 4388 return rk3588_get_pll(sc, RK3588_CRU_GPLL_CON(0)); 4389 case RK3588_PLL_NPLL: 4390 return rk3588_get_pll(sc, RK3588_CRU_NPLL_CON(0)); 4391 case RK3588_PLL_PPLL: 4392 return rk3588_get_pll(sc, RK3588_PHPTOPCRU_PPLL_CON(0)); 4393 case RK3588_PLL_SPLL: 4394 return rkclock_external_frequency("spll"); 4395 case RK3588_XIN24M: 4396 return 24000000; 4397 default: 4398 break; 4399 } 4400 4401 freq = rkclock_get_frequency(sc, idx); 4402 return freq; 4403 } 4404 4405 int 4406 rk3588_set_frequency(void *cookie, uint32_t *cells, uint32_t freq) 4407 { 4408 struct rkclock_softc *sc = cookie; 4409 uint32_t idx = cells[0]; 4410 4411 switch (idx) { 4412 case RK3588_PLL_AUPLL: 4413 return rk3588_set_pll(sc, RK3588_CRU_AUPLL_CON(0), freq); 4414 case RK3588_PLL_GPLL: 4415 return rk3588_set_pll(sc, RK3588_CRU_GPLL_CON(0), freq); 4416 case RK3588_PLL_NPLL: 4417 return rk3588_set_pll(sc, RK3588_CRU_NPLL_CON(0), freq); 4418 case RK3588_PLL_PPLL: 4419 return rk3588_set_pll(sc, RK3588_PHPTOPCRU_PPLL_CON(0), freq); 4420 default: 4421 break; 4422 } 4423 4424 return rkclock_set_frequency(sc, idx, freq); 4425 } 4426 4427 void 4428 rk3588_enable(void *cookie, uint32_t *cells, int on) 4429 { 4430 uint32_t idx = cells[0]; 4431 4432 /* All clocks are enabled upon hardware reset. */ 4433 if (!on) { 4434 printf("%s: 0x%08x\n", __func__, idx); 4435 return; 4436 } 4437 } 4438 4439 void 4440 rk3588_reset(void *cookie, uint32_t *cells, int on) 4441 { 4442 struct rkclock_softc *sc = cookie; 4443 uint32_t idx = cells[0]; 4444 uint32_t bit, mask, reg; 4445 4446 switch (idx) { 4447 case RK3588_SRST_PCIE0_POWER_UP: 4448 reg = RK3588_CRU_SOFTRST_CON(32); 4449 bit = 13; 4450 break; 4451 case RK3588_SRST_PCIE1_POWER_UP: 4452 reg = RK3588_CRU_SOFTRST_CON(32); 4453 bit = 14; 4454 break; 4455 case RK3588_SRST_PCIE2_POWER_UP: 4456 reg = RK3588_CRU_SOFTRST_CON(32); 4457 bit = 15; 4458 break; 4459 case RK3588_SRST_PCIE3_POWER_UP: 4460 reg = RK3588_CRU_SOFTRST_CON(33); 4461 bit = 0; 4462 break; 4463 case RK3588_SRST_PCIE4_POWER_UP: 4464 reg = RK3588_CRU_SOFTRST_CON(33); 4465 bit = 1; 4466 break; 4467 case RK3588_SRST_P_PCIE0: 4468 reg = RK3588_CRU_SOFTRST_CON(33); 4469 bit = 12; 4470 break; 4471 case RK3588_SRST_P_PCIE1: 4472 reg = RK3588_CRU_SOFTRST_CON(33); 4473 bit = 13; 4474 break; 4475 case RK3588_SRST_P_PCIE2: 4476 reg = RK3588_CRU_SOFTRST_CON(33); 4477 bit = 14; 4478 break; 4479 case RK3588_SRST_P_PCIE3: 4480 reg = RK3588_CRU_SOFTRST_CON(33); 4481 bit = 15; 4482 break; 4483 case RK3588_SRST_P_PCIE4: 4484 reg = RK3588_CRU_SOFTRST_CON(34); 4485 bit = 0; 4486 break; 4487 case RK3588_SRST_A_USB3OTG2: 4488 reg = RK3588_CRU_SOFTRST_CON(35); 4489 bit = 7; 4490 break; 4491 case RK3588_SRST_A_USB3OTG0: 4492 reg = RK3588_CRU_SOFTRST_CON(42); 4493 bit = 4; 4494 break; 4495 case RK3588_SRST_A_USB3OTG1: 4496 reg = RK3588_CRU_SOFTRST_CON(42); 4497 bit = 7; 4498 break; 4499 case RK3588_SRST_REF_PIPE_PHY0: 4500 reg = RK3588_CRU_SOFTRST_CON(77); 4501 bit = 6; 4502 break; 4503 case RK3588_SRST_REF_PIPE_PHY1: 4504 reg = RK3588_CRU_SOFTRST_CON(77); 4505 bit = 7; 4506 break; 4507 case RK3588_SRST_REF_PIPE_PHY2: 4508 reg = RK3588_CRU_SOFTRST_CON(77); 4509 bit = 8; 4510 break; 4511 case RK3588_SRST_P_PCIE2_PHY0: 4512 reg = RK3588_PHPTOPCRU_SOFTRST_CON(0); 4513 bit = 5; 4514 break; 4515 case RK3588_SRST_P_PCIE2_PHY1: 4516 reg = RK3588_PHPTOPCRU_SOFTRST_CON(0); 4517 bit = 6; 4518 break; 4519 case RK3588_SRST_P_PCIE2_PHY2: 4520 reg = RK3588_PHPTOPCRU_SOFTRST_CON(0); 4521 bit = 7; 4522 break; 4523 case RK3588_SRST_PCIE30_PHY: 4524 reg = RK3588_PHPTOPCRU_SOFTRST_CON(0); 4525 bit = 10; 4526 break; 4527 default: 4528 printf("%s: 0x%08x\n", __func__, idx); 4529 return; 4530 } 4531 4532 mask = (1 << bit); 4533 HWRITE4(sc, reg, mask << 16 | (on ? mask : 0)); 4534 } 4535