1 /* $OpenBSD: imxccm.c,v 1.29 2022/06/28 23:43:12 naddy Exp $ */ 2 /* 3 * Copyright (c) 2012-2013 Patrick Wildt <patrick@blueri.se> 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/queue.h> 21 #include <sys/malloc.h> 22 #include <sys/sysctl.h> 23 #include <sys/device.h> 24 #include <sys/evcount.h> 25 #include <sys/socket.h> 26 #include <sys/timeout.h> 27 28 #include <machine/intr.h> 29 #include <machine/bus.h> 30 #include <machine/fdt.h> 31 32 #include <dev/ofw/openfirm.h> 33 #include <dev/ofw/ofw_clock.h> 34 #include <dev/ofw/ofw_misc.h> 35 #include <dev/ofw/ofw_regulator.h> 36 #include <dev/ofw/fdt.h> 37 38 #include <dev/fdt/imxanatopvar.h> 39 40 /* registers */ 41 #define CCM_CCR 0x00 42 #define CCM_CCDR 0x04 43 #define CCM_CSR 0x08 44 #define CCM_CCSR 0x0c 45 #define CCM_CACRR 0x10 46 #define CCM_CBCDR 0x14 47 #define CCM_CBCMR 0x18 48 #define CCM_CSCMR1 0x1c 49 #define CCM_CSCMR2 0x20 50 #define CCM_CSCDR1 0x24 51 #define CCM_CS1CDR 0x28 52 #define CCM_CS2CDR 0x2c 53 #define CCM_CDCDR 0x30 54 #define CCM_CHSCCDR 0x34 55 #define CCM_CSCDR2 0x38 56 #define CCM_CSCDR3 0x3c 57 #define CCM_CSCDR4 0x40 58 #define CCM_CDHIPR 0x48 59 #define CCM_CDCR 0x4c 60 #define CCM_CTOR 0x50 61 #define CCM_CLPCR 0x54 62 #define CCM_CISR 0x58 63 #define CCM_CIMR 0x5c 64 #define CCM_CCOSR 0x60 65 #define CCM_CGPR 0x64 66 #define CCM_CCGR0 0x68 67 #define CCM_CCGR1 0x6c 68 #define CCM_CCGR2 0x70 69 #define CCM_CCGR3 0x74 70 #define CCM_CCGR4 0x78 71 #define CCM_CCGR5 0x7c 72 #define CCM_CCGR6 0x80 73 #define CCM_CCGR7 0x84 74 #define CCM_CMEOR 0x88 75 76 /* bits and bytes */ 77 #define CCM_CCSR_PLL3_SW_CLK_SEL (1 << 0) 78 #define CCM_CCSR_PLL2_SW_CLK_SEL (1 << 1) 79 #define CCM_CCSR_PLL1_SW_CLK_SEL (1 << 2) 80 #define CCM_CCSR_STEP_SEL (1 << 8) 81 #define CCM_CBCDR_IPG_PODF_SHIFT 8 82 #define CCM_CBCDR_IPG_PODF_MASK 0x3 83 #define CCM_CBCDR_AHB_PODF_SHIFT 10 84 #define CCM_CBCDR_AHB_PODF_MASK 0x7 85 #define CCM_CBCDR_PERIPH_CLK_SEL_SHIFT 25 86 #define CCM_CBCDR_PERIPH_CLK_SEL_MASK 0x1 87 #define CCM_CBCMR_PERIPH_CLK2_SEL_SHIFT 12 88 #define CCM_CBCMR_PERIPH_CLK2_SEL_MASK 0x3 89 #define CCM_CBCMR_PRE_PERIPH_CLK_SEL_SHIFT 18 90 #define CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK 0x3 91 #define CCM_CSCDR1_USDHCx_CLK_SEL_SHIFT(x) ((x) + 15) 92 #define CCM_CSCDR1_USDHCx_CLK_SEL_MASK 0x1 93 #define CCM_CSCDR1_USDHCx_PODF_MASK 0x7 94 #define CCM_CSCDR1_UART_PODF_MASK 0x7 95 #define CCM_CSCDR2_ECSPI_PODF_SHIFT 19 96 #define CCM_CSCDR2_ECSPI_PODF_MASK 0x7 97 #define CCM_CCGR1_ENET (3 << 10) 98 #define CCM_CCGR4_125M_PCIE (3 << 0) 99 #define CCM_CCGR5_100M_SATA (3 << 4) 100 #define CCM_CSCMR1_PERCLK_CLK_PODF_MASK 0x1f 101 #define CCM_CSCMR1_PERCLK_CLK_SEL_MASK (1 << 6) 102 103 /* Analog registers */ 104 #define CCM_ANALOG_PLL_USB1 0x0010 105 #define CCM_ANALOG_PLL_USB1_SET 0x0014 106 #define CCM_ANALOG_PLL_USB1_CLR 0x0018 107 #define CCM_ANALOG_PLL_USB1_LOCK (1U << 31) 108 #define CCM_ANALOG_PLL_USB1_BYPASS (1 << 16) 109 #define CCM_ANALOG_PLL_USB1_ENABLE (1 << 13) 110 #define CCM_ANALOG_PLL_USB1_POWER (1 << 12) 111 #define CCM_ANALOG_PLL_USB1_EN_USB_CLKS (1 << 6) 112 #define CCM_ANALOG_PLL_USB2 0x0020 113 #define CCM_ANALOG_PLL_USB2_SET 0x0024 114 #define CCM_ANALOG_PLL_USB2_CLR 0x0028 115 #define CCM_ANALOG_PLL_USB2_LOCK (1U << 31) 116 #define CCM_ANALOG_PLL_USB2_BYPASS (1 << 16) 117 #define CCM_ANALOG_PLL_USB2_ENABLE (1 << 13) 118 #define CCM_ANALOG_PLL_USB2_POWER (1 << 12) 119 #define CCM_ANALOG_PLL_USB2_EN_USB_CLKS (1 << 6) 120 #define CCM_ANALOG_PLL_ENET 0x00e0 121 #define CCM_ANALOG_PLL_ENET_SET 0x00e4 122 #define CCM_ANALOG_PLL_ENET_CLR 0x00e8 123 #define CCM_ANALOG_PLL_ENET_LOCK (1U << 31) 124 #define CCM_ANALOG_PLL_ENET_ENABLE_100M (1 << 20) /* i.MX6 */ 125 #define CCM_ANALOG_PLL_ENET_BYPASS (1 << 16) 126 #define CCM_ANALOG_PLL_ENET_ENABLE (1 << 13) /* i.MX6 */ 127 #define CCM_ANALOG_PLL_ENET_POWERDOWN (1 << 12) /* i.MX6 */ 128 #define CCM_ANALOG_PLL_ENET_ENABLE_CLK_125MHZ (1 << 10) /* i.MX7 */ 129 130 /* Int PLL */ 131 #define CCM_14XX_IMX8M_ARM_PLL_GNRL_CTL 0x84 132 #define CCM_14XX_IMX8M_ARM_PLL_DIV_CTL 0x88 133 #define CCM_14XX_IMX8M_SYS_PLL1_GNRL_CTL 0x94 134 #define CCM_14XX_IMX8M_SYS_PLL1_DIV_CTL 0x98 135 #define CCM_INT_PLL_LOCK (1U << 31) 136 #define CCM_INT_PLL_LOCK_SEL (1 << 29) 137 #define CCM_INT_PLL_RST (1 << 9) 138 #define CCM_INT_PLL_BYPASS (1 << 4) 139 #define CCM_INT_PLL_MAIN_DIV_SHIFT 12 140 #define CCM_INT_PLL_MAIN_DIV_MASK 0x3ff 141 #define CCM_INT_PLL_PRE_DIV_SHIFT 4 142 #define CCM_INT_PLL_PRE_DIV_MASK 0x3f 143 #define CCM_INT_PLL_POST_DIV_SHIFT 0 144 #define CCM_INT_PLL_POST_DIV_MASK 0x7 145 146 /* Frac PLL */ 147 #define CCM_FRAC_IMX8M_ARM_PLL0 0x28 148 #define CCM_FRAC_IMX8M_ARM_PLL1 0x2c 149 #define CCM_FRAC_PLL_LOCK (1U << 31) 150 #define CCM_FRAC_PLL_ENABLE (1 << 21) 151 #define CCM_FRAC_PLL_POWERDOWN (1 << 19) 152 #define CCM_FRAC_PLL_REFCLK_SEL_SHIFT 16 153 #define CCM_FRAC_PLL_REFCLK_SEL_MASK 0x3 154 #define CCM_FRAC_PLL_LOCK_SEL (1 << 15) 155 #define CCM_FRAC_PLL_BYPASS (1 << 14) 156 #define CCM_FRAC_PLL_COUNTCLK_SEL (1 << 13) 157 #define CCM_FRAC_PLL_NEWDIV_VAL (1 << 12) 158 #define CCM_FRAC_PLL_NEWDIV_ACK (1 << 11) 159 #define CCM_FRAC_PLL_REFCLK_DIV_VAL_SHIFT 5 160 #define CCM_FRAC_PLL_REFCLK_DIV_VAL_MASK 0x3f 161 #define CCM_FRAC_PLL_OUTPUT_DIV_VAL_SHIFT 0 162 #define CCM_FRAC_PLL_OUTPUT_DIV_VAL_MASK 0x1f 163 #define CCM_FRAC_PLL_FRAC_DIV_CTL_SHIFT 7 164 #define CCM_FRAC_PLL_FRAC_DIV_CTL_MASK 0x1ffffff 165 #define CCM_FRAC_PLL_INT_DIV_CTL_SHIFT 0 166 #define CCM_FRAC_PLL_INT_DIV_CTL_MASK 0x7f 167 #define CCM_FRAC_PLL_DENOM (1 << 24) 168 #define CCM_FRAC_IMX8M_PLLOUT_DIV_CFG 0x78 169 #define CCM_FRAC_IMX8M_PLLOUT_DIV_CFG_ARM_SHIFT 20 170 #define CCM_FRAC_IMX8M_PLLOUT_DIV_CFG_ARM_MASK 0x7 171 172 #define HCLK_FREQ 24000000 173 #define PLL3_60M 60000000 174 #define PLL3_80M 80000000 175 176 #define HREAD4(sc, reg) \ 177 (bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg))) 178 #define HWRITE4(sc, reg, val) \ 179 bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val)) 180 #define HSET4(sc, reg, bits) \ 181 HWRITE4((sc), (reg), HREAD4((sc), (reg)) | (bits)) 182 #define HCLR4(sc, reg, bits) \ 183 HWRITE4((sc), (reg), HREAD4((sc), (reg)) & ~(bits)) 184 185 struct imxccm_gate { 186 uint16_t reg; 187 uint8_t pos; 188 uint16_t parent; 189 }; 190 191 struct imxccm_divider { 192 uint16_t reg; 193 uint16_t shift; 194 uint16_t mask; 195 uint16_t parent; 196 uint16_t fixed; 197 }; 198 199 struct imxccm_mux { 200 uint16_t reg; 201 uint16_t shift; 202 uint16_t mask; 203 }; 204 205 #include "imxccm_clocks.h" 206 207 struct imxccm_softc { 208 struct device sc_dev; 209 bus_space_tag_t sc_iot; 210 bus_space_handle_t sc_ioh; 211 int sc_node; 212 uint32_t sc_phandle; 213 214 struct regmap *sc_anatop; 215 216 const struct imxccm_gate *sc_gates; 217 int sc_ngates; 218 const struct imxccm_divider *sc_divs; 219 int sc_ndivs; 220 const struct imxccm_mux *sc_muxs; 221 int sc_nmuxs; 222 const struct imxccm_divider *sc_predivs; 223 int sc_npredivs; 224 struct clock_device sc_cd; 225 }; 226 227 int imxccm_match(struct device *, void *, void *); 228 void imxccm_attach(struct device *parent, struct device *self, void *args); 229 230 const struct cfattach imxccm_ca = { 231 sizeof (struct imxccm_softc), imxccm_match, imxccm_attach 232 }; 233 234 struct cfdriver imxccm_cd = { 235 NULL, "imxccm", DV_DULL 236 }; 237 238 uint32_t imxccm_get_armclk(struct imxccm_softc *); 239 void imxccm_armclk_set_parent(struct imxccm_softc *, enum imxanatop_clocks); 240 uint32_t imxccm_get_usdhx(struct imxccm_softc *, int x); 241 uint32_t imxccm_get_periphclk(struct imxccm_softc *); 242 uint32_t imxccm_get_ahbclk(struct imxccm_softc *); 243 uint32_t imxccm_get_ipgclk(struct imxccm_softc *); 244 uint32_t imxccm_get_ipg_perclk(struct imxccm_softc *); 245 uint32_t imxccm_get_uartclk(struct imxccm_softc *); 246 uint32_t imxccm_imx8mm_enet(struct imxccm_softc *sc, uint32_t); 247 uint32_t imxccm_imx8mm_ahb(struct imxccm_softc *sc, uint32_t); 248 uint32_t imxccm_imx8mm_i2c(struct imxccm_softc *sc, uint32_t); 249 uint32_t imxccm_imx8mm_uart(struct imxccm_softc *sc, uint32_t); 250 uint32_t imxccm_imx8mm_usdhc(struct imxccm_softc *sc, uint32_t); 251 uint32_t imxccm_imx8mp_enet_qos_timer(struct imxccm_softc *sc, uint32_t); 252 uint32_t imxccm_imx8mp_enet_qos(struct imxccm_softc *sc, uint32_t); 253 uint32_t imxccm_imx8mp_hsio_axi(struct imxccm_softc *sc, uint32_t); 254 uint32_t imxccm_imx8mq_ecspi(struct imxccm_softc *sc, uint32_t); 255 uint32_t imxccm_imx8mq_enet(struct imxccm_softc *sc, uint32_t); 256 uint32_t imxccm_imx8mq_ahb(struct imxccm_softc *sc, uint32_t); 257 uint32_t imxccm_imx8mq_i2c(struct imxccm_softc *sc, uint32_t); 258 uint32_t imxccm_imx8mq_pwm(struct imxccm_softc *sc, uint32_t); 259 uint32_t imxccm_imx8mq_uart(struct imxccm_softc *sc, uint32_t); 260 uint32_t imxccm_imx8mq_usdhc(struct imxccm_softc *sc, uint32_t); 261 uint32_t imxccm_imx8mq_usb(struct imxccm_softc *sc, uint32_t); 262 int imxccm_imx8m_set_div(struct imxccm_softc *, uint32_t, uint64_t, uint64_t); 263 void imxccm_enable(void *, uint32_t *, int); 264 uint32_t imxccm_get_frequency(void *, uint32_t *); 265 int imxccm_set_frequency(void *, uint32_t *, uint32_t); 266 int imxccm_set_parent(void *, uint32_t *, uint32_t *); 267 268 int 269 imxccm_match(struct device *parent, void *match, void *aux) 270 { 271 struct fdt_attach_args *faa = aux; 272 273 return (OF_is_compatible(faa->fa_node, "fsl,imx6q-ccm") || 274 OF_is_compatible(faa->fa_node, "fsl,imx6sl-ccm") || 275 OF_is_compatible(faa->fa_node, "fsl,imx6sx-ccm") || 276 OF_is_compatible(faa->fa_node, "fsl,imx6ul-ccm") || 277 OF_is_compatible(faa->fa_node, "fsl,imx7d-ccm") || 278 OF_is_compatible(faa->fa_node, "fsl,imx8mm-ccm") || 279 OF_is_compatible(faa->fa_node, "fsl,imx8mp-ccm") || 280 OF_is_compatible(faa->fa_node, "fsl,imx8mq-ccm")); 281 } 282 283 void 284 imxccm_attach(struct device *parent, struct device *self, void *aux) 285 { 286 struct imxccm_softc *sc = (struct imxccm_softc *)self; 287 struct fdt_attach_args *faa = aux; 288 289 KASSERT(faa->fa_nreg >= 1); 290 291 sc->sc_node = faa->fa_node; 292 sc->sc_iot = faa->fa_iot; 293 if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr, 294 faa->fa_reg[0].size, 0, &sc->sc_ioh)) 295 panic("%s: bus_space_map failed!", __func__); 296 297 sc->sc_phandle = OF_getpropint(sc->sc_node, "phandle", 0); 298 299 if (OF_is_compatible(sc->sc_node, "fsl,imx8mm-ccm")) { 300 sc->sc_anatop = regmap_bycompatible("fsl,imx8mm-anatop"); 301 KASSERT(sc->sc_anatop != NULL); 302 sc->sc_gates = imx8mm_gates; 303 sc->sc_ngates = nitems(imx8mm_gates); 304 sc->sc_divs = imx8mm_divs; 305 sc->sc_ndivs = nitems(imx8mm_divs); 306 sc->sc_muxs = imx8mm_muxs; 307 sc->sc_nmuxs = nitems(imx8mm_muxs); 308 sc->sc_predivs = imx8mm_predivs; 309 sc->sc_npredivs = nitems(imx8mm_predivs); 310 } else if (OF_is_compatible(sc->sc_node, "fsl,imx8mp-ccm")) { 311 sc->sc_anatop = regmap_bycompatible("fsl,imx8mp-anatop"); 312 KASSERT(sc->sc_anatop != NULL); 313 sc->sc_gates = imx8mp_gates; 314 sc->sc_ngates = nitems(imx8mp_gates); 315 sc->sc_divs = imx8mp_divs; 316 sc->sc_ndivs = nitems(imx8mp_divs); 317 sc->sc_muxs = imx8mp_muxs; 318 sc->sc_nmuxs = nitems(imx8mp_muxs); 319 sc->sc_predivs = imx8mp_predivs; 320 sc->sc_npredivs = nitems(imx8mp_predivs); 321 } else if (OF_is_compatible(sc->sc_node, "fsl,imx8mq-ccm")) { 322 sc->sc_anatop = regmap_bycompatible("fsl,imx8mq-anatop"); 323 KASSERT(sc->sc_anatop != NULL); 324 sc->sc_gates = imx8mq_gates; 325 sc->sc_ngates = nitems(imx8mq_gates); 326 sc->sc_divs = imx8mq_divs; 327 sc->sc_ndivs = nitems(imx8mq_divs); 328 sc->sc_muxs = imx8mq_muxs; 329 sc->sc_nmuxs = nitems(imx8mq_muxs); 330 sc->sc_predivs = imx8mq_predivs; 331 sc->sc_npredivs = nitems(imx8mq_predivs); 332 } else if (OF_is_compatible(sc->sc_node, "fsl,imx7d-ccm")) { 333 sc->sc_gates = imx7d_gates; 334 sc->sc_ngates = nitems(imx7d_gates); 335 sc->sc_divs = imx7d_divs; 336 sc->sc_ndivs = nitems(imx7d_divs); 337 sc->sc_muxs = imx7d_muxs; 338 sc->sc_nmuxs = nitems(imx7d_muxs); 339 } else if (OF_is_compatible(sc->sc_node, "fsl,imx6ul-ccm")) { 340 sc->sc_gates = imx6ul_gates; 341 sc->sc_ngates = nitems(imx6ul_gates); 342 } else { 343 sc->sc_gates = imx6_gates; 344 sc->sc_ngates = nitems(imx6_gates); 345 } 346 347 printf("\n"); 348 349 sc->sc_cd.cd_node = faa->fa_node; 350 sc->sc_cd.cd_cookie = sc; 351 sc->sc_cd.cd_enable = imxccm_enable; 352 sc->sc_cd.cd_get_frequency = imxccm_get_frequency; 353 sc->sc_cd.cd_set_frequency = imxccm_set_frequency; 354 sc->sc_cd.cd_set_parent = imxccm_set_parent; 355 clock_register(&sc->sc_cd); 356 } 357 358 uint32_t 359 imxccm_get_armclk(struct imxccm_softc *sc) 360 { 361 uint32_t ccsr = HREAD4(sc, CCM_CCSR); 362 363 if (!(ccsr & CCM_CCSR_PLL1_SW_CLK_SEL)) 364 return imxanatop_decode_pll(ARM_PLL1, HCLK_FREQ); 365 else if (ccsr & CCM_CCSR_STEP_SEL) 366 return imxanatop_get_pll2_pfd(2); 367 else 368 return HCLK_FREQ; 369 } 370 371 void 372 imxccm_armclk_set_parent(struct imxccm_softc *sc, enum imxanatop_clocks clock) 373 { 374 switch (clock) 375 { 376 case ARM_PLL1: 377 /* jump onto pll1 */ 378 HCLR4(sc, CCM_CCSR, CCM_CCSR_PLL1_SW_CLK_SEL); 379 /* put step clk on OSC, power saving */ 380 HCLR4(sc, CCM_CCSR, CCM_CCSR_STEP_SEL); 381 break; 382 case OSC: 383 /* put step clk on OSC */ 384 HCLR4(sc, CCM_CCSR, CCM_CCSR_STEP_SEL); 385 /* jump onto step clk */ 386 HSET4(sc, CCM_CCSR, CCM_CCSR_PLL1_SW_CLK_SEL); 387 break; 388 case SYS_PLL2_PFD2: 389 /* put step clk on pll2-pfd2 400 MHz */ 390 HSET4(sc, CCM_CCSR, CCM_CCSR_STEP_SEL); 391 /* jump onto step clk */ 392 HSET4(sc, CCM_CCSR, CCM_CCSR_PLL1_SW_CLK_SEL); 393 break; 394 default: 395 panic("%s: parent not possible for arm clk", __func__); 396 } 397 } 398 399 uint32_t 400 imxccm_get_ecspiclk(struct imxccm_softc *sc) 401 { 402 uint32_t clkroot = PLL3_60M; 403 uint32_t podf = HREAD4(sc, CCM_CSCDR2); 404 405 podf >>= CCM_CSCDR2_ECSPI_PODF_SHIFT; 406 podf &= CCM_CSCDR2_ECSPI_PODF_MASK; 407 408 return clkroot / (podf + 1); 409 } 410 411 unsigned int 412 imxccm_get_usdhx(struct imxccm_softc *sc, int x) 413 { 414 uint32_t cscmr1 = HREAD4(sc, CCM_CSCMR1); 415 uint32_t cscdr1 = HREAD4(sc, CCM_CSCDR1); 416 uint32_t podf, clkroot; 417 418 // Odd bitsetting. Damn you. 419 if (x == 1) 420 podf = ((cscdr1 >> 11) & CCM_CSCDR1_USDHCx_PODF_MASK); 421 else 422 podf = ((cscdr1 >> (10 + 3*x)) & CCM_CSCDR1_USDHCx_PODF_MASK); 423 424 if (cscmr1 & (1 << CCM_CSCDR1_USDHCx_CLK_SEL_SHIFT(x))) 425 clkroot = imxanatop_get_pll2_pfd(0); // 352 MHz 426 else 427 clkroot = imxanatop_get_pll2_pfd(2); // 396 MHz 428 429 return clkroot / (podf + 1); 430 } 431 432 uint32_t 433 imxccm_get_uartclk(struct imxccm_softc *sc) 434 { 435 uint32_t clkroot = PLL3_80M; 436 uint32_t podf = HREAD4(sc, CCM_CSCDR1) & CCM_CSCDR1_UART_PODF_MASK; 437 438 return clkroot / (podf + 1); 439 } 440 441 uint32_t 442 imxccm_get_periphclk(struct imxccm_softc *sc) 443 { 444 if ((HREAD4(sc, CCM_CBCDR) >> CCM_CBCDR_PERIPH_CLK_SEL_SHIFT) 445 & CCM_CBCDR_PERIPH_CLK_SEL_MASK) { 446 switch((HREAD4(sc, CCM_CBCMR) 447 >> CCM_CBCMR_PERIPH_CLK2_SEL_SHIFT) & CCM_CBCMR_PERIPH_CLK2_SEL_MASK) { 448 case 0: 449 return imxanatop_decode_pll(USB1_PLL3, HCLK_FREQ); 450 case 1: 451 case 2: 452 return HCLK_FREQ; 453 default: 454 return 0; 455 } 456 457 } else { 458 switch((HREAD4(sc, CCM_CBCMR) 459 >> CCM_CBCMR_PRE_PERIPH_CLK_SEL_SHIFT) & CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK) { 460 default: 461 case 0: 462 return imxanatop_decode_pll(SYS_PLL2, HCLK_FREQ); 463 case 1: 464 return imxanatop_get_pll2_pfd(2); // 396 MHz 465 case 2: 466 return imxanatop_get_pll2_pfd(0); // 352 MHz 467 case 3: 468 return imxanatop_get_pll2_pfd(2) / 2; // 198 MHz 469 } 470 } 471 } 472 473 uint32_t 474 imxccm_get_ahbclk(struct imxccm_softc *sc) 475 { 476 uint32_t ahb_podf; 477 478 ahb_podf = (HREAD4(sc, CCM_CBCDR) >> CCM_CBCDR_AHB_PODF_SHIFT) 479 & CCM_CBCDR_AHB_PODF_MASK; 480 return imxccm_get_periphclk(sc) / (ahb_podf + 1); 481 } 482 483 uint32_t 484 imxccm_get_ipgclk(struct imxccm_softc *sc) 485 { 486 uint32_t ipg_podf; 487 488 ipg_podf = (HREAD4(sc, CCM_CBCDR) >> CCM_CBCDR_IPG_PODF_SHIFT) 489 & CCM_CBCDR_IPG_PODF_MASK; 490 return imxccm_get_ahbclk(sc) / (ipg_podf + 1); 491 } 492 493 uint32_t 494 imxccm_get_ipg_perclk(struct imxccm_softc *sc) 495 { 496 uint32_t cscmr1 = HREAD4(sc, CCM_CSCMR1); 497 uint32_t freq, ipg_podf; 498 499 if (sc->sc_gates == imx6ul_gates && 500 cscmr1 & CCM_CSCMR1_PERCLK_CLK_SEL_MASK) 501 freq = HCLK_FREQ; 502 else 503 freq = imxccm_get_ipgclk(sc); 504 505 ipg_podf = cscmr1 & CCM_CSCMR1_PERCLK_CLK_PODF_MASK; 506 507 return freq / (ipg_podf + 1); 508 } 509 510 void 511 imxccm_imx6_enable_pll_enet(struct imxccm_softc *sc, int on) 512 { 513 KASSERT(on); 514 515 regmap_write_4(sc->sc_anatop, CCM_ANALOG_PLL_ENET_CLR, 516 CCM_ANALOG_PLL_ENET_POWERDOWN); 517 518 /* Wait for the PLL to lock. */ 519 while ((regmap_read_4(sc->sc_anatop, 520 CCM_ANALOG_PLL_ENET) & CCM_ANALOG_PLL_ENET_LOCK) == 0) 521 ; 522 523 regmap_write_4(sc->sc_anatop, CCM_ANALOG_PLL_ENET_CLR, 524 CCM_ANALOG_PLL_ENET_BYPASS); 525 } 526 527 void 528 imxccm_imx6_enable_pll_usb1(struct imxccm_softc *sc, int on) 529 { 530 KASSERT(on); 531 532 regmap_write_4(sc->sc_anatop, CCM_ANALOG_PLL_USB1_SET, 533 CCM_ANALOG_PLL_USB1_POWER); 534 535 /* Wait for the PLL to lock. */ 536 while ((regmap_read_4(sc->sc_anatop, 537 CCM_ANALOG_PLL_USB1) & CCM_ANALOG_PLL_USB1_LOCK) == 0) 538 ; 539 540 regmap_write_4(sc->sc_anatop, CCM_ANALOG_PLL_USB1_CLR, 541 CCM_ANALOG_PLL_USB1_BYPASS); 542 } 543 544 void 545 imxccm_imx6_enable_pll_usb2(struct imxccm_softc *sc, int on) 546 { 547 KASSERT(on); 548 549 regmap_write_4(sc->sc_anatop, CCM_ANALOG_PLL_USB2_SET, 550 CCM_ANALOG_PLL_USB2_POWER); 551 552 /* Wait for the PLL to lock. */ 553 while ((regmap_read_4(sc->sc_anatop, 554 CCM_ANALOG_PLL_USB2) & CCM_ANALOG_PLL_USB2_LOCK) == 0) 555 ; 556 557 regmap_write_4(sc->sc_anatop, CCM_ANALOG_PLL_USB2_CLR, 558 CCM_ANALOG_PLL_USB2_BYPASS); 559 } 560 561 uint32_t 562 imxccm_imx7d_enet(struct imxccm_softc *sc, uint32_t idx) 563 { 564 uint32_t mux; 565 566 if (idx >= sc->sc_nmuxs || sc->sc_muxs[idx].reg == 0) 567 return 0; 568 569 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 570 mux >>= sc->sc_muxs[idx].shift; 571 mux &= sc->sc_muxs[idx].mask; 572 573 switch (mux) { 574 case 0: 575 return clock_get_frequency(sc->sc_node, "osc"); 576 case 7: 577 return 392000000; /* pll_sys_pfd4_clk XXX not fixed */ 578 default: 579 printf("%s: 0x%08x 0x%08x\n", __func__, idx, mux); 580 return 0; 581 } 582 } 583 584 uint32_t 585 imxccm_imx7d_i2c(struct imxccm_softc *sc, uint32_t idx) 586 { 587 uint32_t mux; 588 589 if (idx >= sc->sc_nmuxs || sc->sc_muxs[idx].reg == 0) 590 return 0; 591 592 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 593 mux >>= sc->sc_muxs[idx].shift; 594 mux &= sc->sc_muxs[idx].mask; 595 596 switch (mux) { 597 case 0: 598 return clock_get_frequency(sc->sc_node, "osc"); 599 case 1: 600 return 120000000; /* pll_sys_main_120m_clk */ 601 default: 602 printf("%s: 0x%08x 0x%08x\n", __func__, idx, mux); 603 return 0; 604 } 605 } 606 607 uint32_t 608 imxccm_imx7d_uart(struct imxccm_softc *sc, uint32_t idx) 609 { 610 uint32_t mux; 611 612 if (idx >= sc->sc_nmuxs || sc->sc_muxs[idx].reg == 0) 613 return 0; 614 615 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 616 mux >>= sc->sc_muxs[idx].shift; 617 mux &= sc->sc_muxs[idx].mask; 618 619 switch (mux) { 620 case 0: 621 return clock_get_frequency(sc->sc_node, "osc"); 622 default: 623 printf("%s: 0x%08x 0x%08x\n", __func__, idx, mux); 624 return 0; 625 } 626 } 627 628 uint32_t 629 imxccm_imx7d_usdhc(struct imxccm_softc *sc, uint32_t idx) 630 { 631 uint32_t mux; 632 633 if (idx >= sc->sc_nmuxs || sc->sc_muxs[idx].reg == 0) 634 return 0; 635 636 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 637 mux >>= sc->sc_muxs[idx].shift; 638 mux &= sc->sc_muxs[idx].mask; 639 640 switch (mux) { 641 case 0: 642 return clock_get_frequency(sc->sc_node, "osc"); 643 case 1: 644 return 392000000; /* pll_sys_pfd0_392m_clk */ 645 default: 646 printf("%s: 0x%08x 0x%08x\n", __func__, idx, mux); 647 return 0; 648 } 649 } 650 651 uint32_t 652 imxccm_imx8mm_get_pll(struct imxccm_softc *sc, uint32_t idx) 653 { 654 uint64_t main_div, pre_div, post_div, div; 655 uint32_t pll0, pll1; 656 uint64_t freq; 657 658 switch (idx) { 659 case IMX8MM_ARM_PLL: 660 pll0 = regmap_read_4(sc->sc_anatop, 661 CCM_14XX_IMX8M_ARM_PLL_GNRL_CTL); 662 pll1 = regmap_read_4(sc->sc_anatop, 663 CCM_14XX_IMX8M_ARM_PLL_DIV_CTL); 664 div = 1; 665 break; 666 default: 667 printf("%s: 0x%08x\n", __func__, idx); 668 return 0; 669 } 670 671 freq = clock_get_frequency(sc->sc_node, "osc_24m"); 672 if (pll0 & CCM_INT_PLL_BYPASS) 673 return freq; 674 675 main_div = (pll1 >> CCM_INT_PLL_MAIN_DIV_SHIFT) & 676 CCM_INT_PLL_MAIN_DIV_MASK; 677 pre_div = (pll1 >> CCM_INT_PLL_PRE_DIV_SHIFT) & 678 CCM_INT_PLL_PRE_DIV_MASK; 679 post_div = (pll1 >> CCM_INT_PLL_POST_DIV_SHIFT) & 680 CCM_INT_PLL_POST_DIV_MASK; 681 682 freq = freq * main_div; 683 freq = freq / (pre_div * (1 << post_div) * div); 684 return freq; 685 } 686 687 int 688 imxccm_imx8mm_set_pll(struct imxccm_softc *sc, uint32_t idx, uint64_t freq) 689 { 690 uint64_t main_div, pre_div, post_div; 691 uint32_t pll0, pll1, reg; 692 int i; 693 694 switch (idx) { 695 case IMX8MM_ARM_PLL: 696 pre_div = 3; 697 switch (freq) { 698 case 1800000000U: 699 main_div = 225; 700 post_div = 0; 701 break; 702 case 1600000000U: 703 main_div = 200; 704 post_div = 0; 705 break; 706 case 1200000000U: 707 main_div = 300; 708 post_div = 1; 709 break; 710 case 1000000000U: 711 main_div = 250; 712 post_div = 1; 713 break; 714 case 800000000U: 715 main_div = 200; 716 post_div = 1; 717 break; 718 case 750000000U: 719 main_div = 250; 720 post_div = 2; 721 break; 722 case 700000000U: 723 main_div = 350; 724 post_div = 2; 725 break; 726 case 600000000U: 727 main_div = 300; 728 post_div = 2; 729 break; 730 default: 731 printf("%s: 0x%08x\n", __func__, idx); 732 return -1; 733 } 734 pll0 = CCM_14XX_IMX8M_ARM_PLL_GNRL_CTL; 735 pll1 = CCM_14XX_IMX8M_ARM_PLL_DIV_CTL; 736 break; 737 default: 738 printf("%s: 0x%08x\n", __func__, idx); 739 return -1; 740 } 741 742 regmap_write_4(sc->sc_anatop, pll0, 743 regmap_read_4(sc->sc_anatop, pll0) | 744 CCM_INT_PLL_LOCK_SEL); 745 regmap_write_4(sc->sc_anatop, pll0, 746 regmap_read_4(sc->sc_anatop, pll0) & 747 ~CCM_INT_PLL_RST); 748 regmap_write_4(sc->sc_anatop, pll1, 749 main_div << CCM_INT_PLL_MAIN_DIV_SHIFT | 750 pre_div << CCM_INT_PLL_PRE_DIV_SHIFT | 751 post_div << CCM_INT_PLL_POST_DIV_SHIFT); 752 delay(3); 753 regmap_write_4(sc->sc_anatop, pll0, 754 regmap_read_4(sc->sc_anatop, pll0) | 755 CCM_INT_PLL_RST); 756 for (i = 0; i < 5000; i++) { 757 reg = regmap_read_4(sc->sc_anatop, pll0); 758 if (reg & CCM_INT_PLL_LOCK) 759 break; 760 delay(10); 761 } 762 if (i == 5000) 763 printf("%s: timeout\n", __func__); 764 regmap_write_4(sc->sc_anatop, pll0, 765 regmap_read_4(sc->sc_anatop, pll0) & 766 ~CCM_INT_PLL_BYPASS); 767 768 return 0; 769 } 770 771 uint32_t 772 imxccm_imx8mm_enet(struct imxccm_softc *sc, uint32_t idx) 773 { 774 uint32_t mux; 775 776 if (idx >= sc->sc_nmuxs || sc->sc_muxs[idx].reg == 0) 777 return 0; 778 779 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 780 mux >>= sc->sc_muxs[idx].shift; 781 mux &= sc->sc_muxs[idx].mask; 782 783 switch (mux) { 784 case 0: 785 return clock_get_frequency(sc->sc_node, "osc_24m"); 786 case 1: 787 return 266 * 1000 * 1000; /* sys1_pll_266m */ 788 default: 789 printf("%s: 0x%08x 0x%08x\n", __func__, idx, mux); 790 return 0; 791 } 792 } 793 794 uint32_t 795 imxccm_imx8mm_ahb(struct imxccm_softc *sc, uint32_t idx) 796 { 797 uint32_t mux; 798 799 if (idx >= sc->sc_nmuxs || sc->sc_muxs[idx].reg == 0) 800 return 0; 801 802 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 803 mux >>= sc->sc_muxs[idx].shift; 804 mux &= sc->sc_muxs[idx].mask; 805 806 switch (mux) { 807 case 0: 808 return clock_get_frequency(sc->sc_node, "osc_24m"); 809 case 1: 810 return 133 * 1000 * 1000; /* sys_pll1_133m */ 811 case 2: 812 return 800 * 1000 * 1000; /* sys_pll1_800m */ 813 case 3: 814 return 400 * 1000 * 1000; /* sys_pll1_400m */ 815 case 4: 816 return 125 * 1000 * 1000; /* sys_pll2_125m */ 817 default: 818 printf("%s: 0x%08x 0x%08x\n", __func__, idx, mux); 819 return 0; 820 } 821 } 822 823 uint32_t 824 imxccm_imx8mm_i2c(struct imxccm_softc *sc, uint32_t idx) 825 { 826 uint32_t mux; 827 828 if (idx >= sc->sc_nmuxs || sc->sc_muxs[idx].reg == 0) 829 return 0; 830 831 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 832 mux >>= sc->sc_muxs[idx].shift; 833 mux &= sc->sc_muxs[idx].mask; 834 835 switch (mux) { 836 case 0: 837 return clock_get_frequency(sc->sc_node, "osc_24m"); 838 default: 839 printf("%s: 0x%08x 0x%08x\n", __func__, idx, mux); 840 return 0; 841 } 842 } 843 844 uint32_t 845 imxccm_imx8mm_uart(struct imxccm_softc *sc, uint32_t idx) 846 { 847 uint32_t mux; 848 849 if (idx >= sc->sc_nmuxs || sc->sc_muxs[idx].reg == 0) 850 return 0; 851 852 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 853 mux >>= sc->sc_muxs[idx].shift; 854 mux &= sc->sc_muxs[idx].mask; 855 856 switch (mux) { 857 case 0: 858 return clock_get_frequency(sc->sc_node, "osc_24m"); 859 default: 860 printf("%s: 0x%08x 0x%08x\n", __func__, idx, mux); 861 return 0; 862 } 863 } 864 865 uint32_t 866 imxccm_imx8mm_usdhc(struct imxccm_softc *sc, uint32_t idx) 867 { 868 uint32_t mux; 869 870 if (idx >= sc->sc_nmuxs || sc->sc_muxs[idx].reg == 0) 871 return 0; 872 873 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 874 mux >>= sc->sc_muxs[idx].shift; 875 mux &= sc->sc_muxs[idx].mask; 876 877 switch (mux) { 878 case 0: 879 return clock_get_frequency(sc->sc_node, "osc_24m"); 880 case 1: 881 return 400 * 1000 * 1000; /* sys1_pll_400m */ 882 default: 883 printf("%s: 0x%08x 0x%08x\n", __func__, idx, mux); 884 return 0; 885 } 886 } 887 888 uint32_t 889 imxccm_imx8mp_enet_qos(struct imxccm_softc *sc, uint32_t idx) 890 { 891 uint32_t mux; 892 893 if (idx >= sc->sc_nmuxs || sc->sc_muxs[idx].reg == 0) 894 return 0; 895 896 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 897 mux >>= sc->sc_muxs[idx].shift; 898 mux &= sc->sc_muxs[idx].mask; 899 900 switch (mux) { 901 case 0: 902 return clock_get_frequency(sc->sc_node, "osc_24m"); 903 case 1: 904 return 125 * 1000 * 1000; /* sys2_pll_125m */ 905 default: 906 printf("%s: 0x%08x 0x%08x\n", __func__, idx, mux); 907 return 0; 908 } 909 } 910 911 uint32_t 912 imxccm_imx8mp_enet_qos_timer(struct imxccm_softc *sc, uint32_t idx) 913 { 914 uint32_t mux; 915 916 if (idx >= sc->sc_nmuxs || sc->sc_muxs[idx].reg == 0) 917 return 0; 918 919 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 920 mux >>= sc->sc_muxs[idx].shift; 921 mux &= sc->sc_muxs[idx].mask; 922 923 switch (mux) { 924 case 0: 925 return clock_get_frequency(sc->sc_node, "osc_24m"); 926 case 1: 927 return 100 * 1000 * 1000; /* sys2_pll_100m */ 928 default: 929 printf("%s: 0x%08x 0x%08x\n", __func__, idx, mux); 930 return 0; 931 } 932 } 933 934 uint32_t 935 imxccm_imx8mp_hsio_axi(struct imxccm_softc *sc, uint32_t idx) 936 { 937 uint32_t mux; 938 939 if (idx >= sc->sc_nmuxs || sc->sc_muxs[idx].reg == 0) 940 return 0; 941 942 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 943 mux >>= sc->sc_muxs[idx].shift; 944 mux &= sc->sc_muxs[idx].mask; 945 946 switch (mux) { 947 case 0: 948 return clock_get_frequency(sc->sc_node, "osc_24m"); 949 case 1: 950 return 500 * 1000 * 1000; /* sys2_pll_500m */ 951 default: 952 printf("%s: 0x%08x 0x%08x\n", __func__, idx, mux); 953 return 0; 954 } 955 } 956 957 uint32_t 958 imxccm_imx8mq_ecspi(struct imxccm_softc *sc, uint32_t idx) 959 { 960 uint32_t mux; 961 962 if (idx >= sc->sc_nmuxs || sc->sc_muxs[idx].reg == 0) 963 return 0; 964 965 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 966 mux >>= sc->sc_muxs[idx].shift; 967 mux &= sc->sc_muxs[idx].mask; 968 969 switch (mux) { 970 case 0: 971 return clock_get_frequency(sc->sc_node, "osc_25m"); 972 case 1: 973 return 200 * 1000 * 1000; /* sys2_pll_200m */ 974 default: 975 printf("%s: 0x%08x 0x%08x\n", __func__, idx, mux); 976 return 0; 977 } 978 } 979 980 uint32_t 981 imxccm_imx8mq_enet(struct imxccm_softc *sc, uint32_t idx) 982 { 983 uint32_t mux; 984 985 if (idx >= sc->sc_nmuxs || sc->sc_muxs[idx].reg == 0) 986 return 0; 987 988 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 989 mux >>= sc->sc_muxs[idx].shift; 990 mux &= sc->sc_muxs[idx].mask; 991 992 switch (mux) { 993 case 0: 994 return clock_get_frequency(sc->sc_node, "osc_25m"); 995 case 1: 996 return 266 * 1000 * 1000; /* sys1_pll_266m */ 997 default: 998 printf("%s: 0x%08x 0x%08x\n", __func__, idx, mux); 999 return 0; 1000 } 1001 } 1002 1003 uint32_t 1004 imxccm_imx8mq_ahb(struct imxccm_softc *sc, uint32_t idx) 1005 { 1006 uint32_t mux; 1007 1008 if (idx >= sc->sc_nmuxs || sc->sc_muxs[idx].reg == 0) 1009 return 0; 1010 1011 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 1012 mux >>= sc->sc_muxs[idx].shift; 1013 mux &= sc->sc_muxs[idx].mask; 1014 1015 switch (mux) { 1016 case 0: 1017 return clock_get_frequency(sc->sc_node, "osc_25m"); 1018 case 1: 1019 return 133 * 1000 * 1000; /* sys1_pll_133m */ 1020 case 2: 1021 return 800 * 1000 * 1000; /* sys1_pll_800m */ 1022 case 3: 1023 return 400 * 1000 * 1000; /* sys1_pll_400m */ 1024 case 4: 1025 return 125 * 1000 * 1000; /* sys2_pll_125m */ 1026 default: 1027 printf("%s: 0x%08x 0x%08x\n", __func__, idx, mux); 1028 return 0; 1029 } 1030 } 1031 1032 uint32_t 1033 imxccm_imx8mq_i2c(struct imxccm_softc *sc, uint32_t idx) 1034 { 1035 uint32_t mux; 1036 1037 if (idx >= sc->sc_nmuxs || sc->sc_muxs[idx].reg == 0) 1038 return 0; 1039 1040 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 1041 mux >>= sc->sc_muxs[idx].shift; 1042 mux &= sc->sc_muxs[idx].mask; 1043 1044 switch (mux) { 1045 case 0: 1046 return clock_get_frequency(sc->sc_node, "osc_25m"); 1047 default: 1048 printf("%s: 0x%08x 0x%08x\n", __func__, idx, mux); 1049 return 0; 1050 } 1051 } 1052 1053 uint32_t 1054 imxccm_imx8mq_pwm(struct imxccm_softc *sc, uint32_t idx) 1055 { 1056 uint32_t mux; 1057 1058 if (idx >= sc->sc_nmuxs || sc->sc_muxs[idx].reg == 0) 1059 return 0; 1060 1061 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 1062 mux >>= sc->sc_muxs[idx].shift; 1063 mux &= sc->sc_muxs[idx].mask; 1064 1065 switch (mux) { 1066 case 0: 1067 return clock_get_frequency(sc->sc_node, "osc_25m"); 1068 case 1: 1069 return 100 * 1000 * 1000; /* sys1_pll_100m */ 1070 case 2: 1071 return 160 * 1000 * 1000; /* sys1_pll_160m */ 1072 case 3: 1073 return 40 * 1000 * 1000; /* sys1_pll_40m */ 1074 default: 1075 printf("%s: 0x%08x 0x%08x\n", __func__, idx, mux); 1076 return 0; 1077 } 1078 } 1079 1080 uint32_t 1081 imxccm_imx8mq_uart(struct imxccm_softc *sc, uint32_t idx) 1082 { 1083 uint32_t mux; 1084 1085 if (idx >= sc->sc_nmuxs || sc->sc_muxs[idx].reg == 0) 1086 return 0; 1087 1088 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 1089 mux >>= sc->sc_muxs[idx].shift; 1090 mux &= sc->sc_muxs[idx].mask; 1091 1092 switch (mux) { 1093 case 0: 1094 return clock_get_frequency(sc->sc_node, "osc_25m"); 1095 default: 1096 printf("%s: 0x%08x 0x%08x\n", __func__, idx, mux); 1097 return 0; 1098 } 1099 } 1100 1101 uint32_t 1102 imxccm_imx8mq_usdhc(struct imxccm_softc *sc, uint32_t idx) 1103 { 1104 uint32_t mux; 1105 1106 if (idx >= sc->sc_nmuxs || sc->sc_muxs[idx].reg == 0) 1107 return 0; 1108 1109 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 1110 mux >>= sc->sc_muxs[idx].shift; 1111 mux &= sc->sc_muxs[idx].mask; 1112 1113 switch (mux) { 1114 case 0: 1115 return clock_get_frequency(sc->sc_node, "osc_25m"); 1116 case 1: 1117 return 400 * 1000 * 1000; /* sys1_pll_400m */ 1118 default: 1119 printf("%s: 0x%08x 0x%08x\n", __func__, idx, mux); 1120 return 0; 1121 } 1122 } 1123 1124 uint32_t 1125 imxccm_imx8mq_usb(struct imxccm_softc *sc, uint32_t idx) 1126 { 1127 uint32_t mux; 1128 1129 if (idx >= sc->sc_nmuxs || sc->sc_muxs[idx].reg == 0) 1130 return 0; 1131 1132 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 1133 mux >>= sc->sc_muxs[idx].shift; 1134 mux &= sc->sc_muxs[idx].mask; 1135 1136 switch (mux) { 1137 case 0: 1138 return clock_get_frequency(sc->sc_node, "osc_25m"); 1139 case 1: 1140 if (idx == IMX8MQ_CLK_USB_CORE_REF || 1141 idx == IMX8MQ_CLK_USB_PHY_REF) 1142 return 100 * 1000 * 1000; /* sys1_pll_100m */ 1143 if (idx == IMX8MQ_CLK_USB_BUS) 1144 return 500 * 1000 * 1000; /* sys2_pll_500m */ 1145 printf("%s: 0x%08x 0x%08x\n", __func__, idx, mux); 1146 return 0; 1147 default: 1148 printf("%s: 0x%08x 0x%08x\n", __func__, idx, mux); 1149 return 0; 1150 } 1151 } 1152 1153 uint32_t 1154 imxccm_imx8mq_get_pll(struct imxccm_softc *sc, uint32_t idx) 1155 { 1156 uint32_t divr_val, divq_val, divf_val; 1157 uint32_t divff, divfi; 1158 uint32_t pllout_div; 1159 uint32_t pll0, pll1; 1160 uint32_t freq; 1161 uint32_t mux; 1162 1163 pllout_div = regmap_read_4(sc->sc_anatop, CCM_FRAC_IMX8M_PLLOUT_DIV_CFG); 1164 1165 switch (idx) { 1166 case IMX8MQ_ARM_PLL: 1167 pll0 = regmap_read_4(sc->sc_anatop, CCM_FRAC_IMX8M_ARM_PLL0); 1168 pll1 = regmap_read_4(sc->sc_anatop, CCM_FRAC_IMX8M_ARM_PLL1); 1169 pllout_div >>= CCM_FRAC_IMX8M_PLLOUT_DIV_CFG_ARM_SHIFT; 1170 pllout_div &= CCM_FRAC_IMX8M_PLLOUT_DIV_CFG_ARM_MASK; 1171 break; 1172 default: 1173 printf("%s: 0x%08x\n", __func__, idx); 1174 return 0; 1175 } 1176 1177 if (pll0 & CCM_FRAC_PLL_POWERDOWN) 1178 return 0; 1179 1180 if ((pll0 & CCM_FRAC_PLL_ENABLE) == 0) 1181 return 0; 1182 1183 mux = (pll0 >> CCM_FRAC_PLL_REFCLK_SEL_SHIFT) & 1184 CCM_FRAC_PLL_REFCLK_SEL_MASK; 1185 switch (mux) { 1186 case 0: 1187 freq = clock_get_frequency(sc->sc_node, "osc_25m"); 1188 break; 1189 case 1: 1190 case 2: 1191 freq = clock_get_frequency(sc->sc_node, "osc_27m"); 1192 break; 1193 default: 1194 printf("%s: 0x%08x 0x%08x\n", __func__, idx, mux); 1195 return 0; 1196 } 1197 1198 if (pll0 & CCM_FRAC_PLL_BYPASS) 1199 return freq; 1200 1201 divr_val = (pll0 >> CCM_FRAC_PLL_REFCLK_DIV_VAL_SHIFT) & 1202 CCM_FRAC_PLL_REFCLK_DIV_VAL_MASK; 1203 divq_val = pll0 & CCM_FRAC_PLL_OUTPUT_DIV_VAL_MASK; 1204 divff = (pll1 >> CCM_FRAC_PLL_FRAC_DIV_CTL_SHIFT) & 1205 CCM_FRAC_PLL_FRAC_DIV_CTL_MASK; 1206 divfi = pll1 & CCM_FRAC_PLL_INT_DIV_CTL_MASK; 1207 divf_val = 1 + divfi + divff / CCM_FRAC_PLL_DENOM; 1208 1209 freq = freq / (divr_val + 1) * 8 * divf_val / ((divq_val + 1) * 2); 1210 return freq / (pllout_div + 1); 1211 } 1212 1213 int 1214 imxccm_imx8mq_set_pll(struct imxccm_softc *sc, uint32_t idx, uint64_t freq) 1215 { 1216 uint64_t divff, divfi, divr; 1217 uint32_t pllout_div; 1218 uint32_t pll0, pll1; 1219 uint32_t mux, reg; 1220 uint64_t pfreq; 1221 int i; 1222 1223 pllout_div = regmap_read_4(sc->sc_anatop, CCM_FRAC_IMX8M_PLLOUT_DIV_CFG); 1224 1225 switch (idx) { 1226 case IMX8MQ_ARM_PLL: 1227 pll0 = CCM_FRAC_IMX8M_ARM_PLL0; 1228 pll1 = CCM_FRAC_IMX8M_ARM_PLL1; 1229 pllout_div >>= CCM_FRAC_IMX8M_PLLOUT_DIV_CFG_ARM_SHIFT; 1230 pllout_div &= CCM_FRAC_IMX8M_PLLOUT_DIV_CFG_ARM_MASK; 1231 /* XXX: Assume fixed divider to ease math. */ 1232 KASSERT(pllout_div == 0); 1233 divr = 5; 1234 break; 1235 default: 1236 printf("%s: 0x%08x\n", __func__, idx); 1237 return -1; 1238 } 1239 1240 reg = regmap_read_4(sc->sc_anatop, pll0); 1241 mux = (reg >> CCM_FRAC_PLL_REFCLK_SEL_SHIFT) & 1242 CCM_FRAC_PLL_REFCLK_SEL_MASK; 1243 switch (mux) { 1244 case 0: 1245 pfreq = clock_get_frequency(sc->sc_node, "osc_25m"); 1246 break; 1247 case 1: 1248 case 2: 1249 pfreq = clock_get_frequency(sc->sc_node, "osc_27m"); 1250 break; 1251 default: 1252 printf("%s: 0x%08x 0x%08x\n", __func__, idx, mux); 1253 return -1; 1254 } 1255 1256 /* Frac divider follows the PLL */ 1257 freq *= divr; 1258 1259 /* PLL calculation */ 1260 freq *= 2; 1261 pfreq *= 8; 1262 divfi = freq / pfreq; 1263 divff = (uint64_t)(freq - divfi * pfreq); 1264 divff = (divff * CCM_FRAC_PLL_DENOM) / pfreq; 1265 1266 reg = regmap_read_4(sc->sc_anatop, pll1); 1267 reg &= ~(CCM_FRAC_PLL_FRAC_DIV_CTL_MASK << CCM_FRAC_PLL_FRAC_DIV_CTL_SHIFT); 1268 reg |= divff << CCM_FRAC_PLL_FRAC_DIV_CTL_SHIFT; 1269 reg &= ~(CCM_FRAC_PLL_INT_DIV_CTL_MASK << CCM_FRAC_PLL_INT_DIV_CTL_SHIFT); 1270 reg |= (divfi - 1) << CCM_FRAC_PLL_INT_DIV_CTL_SHIFT; 1271 regmap_write_4(sc->sc_anatop, pll1, reg); 1272 1273 reg = regmap_read_4(sc->sc_anatop, pll0); 1274 reg &= ~CCM_FRAC_PLL_OUTPUT_DIV_VAL_MASK; 1275 reg &= ~(CCM_FRAC_PLL_REFCLK_DIV_VAL_MASK << CCM_FRAC_PLL_REFCLK_DIV_VAL_SHIFT); 1276 reg |= (divr - 1) << CCM_FRAC_PLL_REFCLK_DIV_VAL_SHIFT; 1277 regmap_write_4(sc->sc_anatop, pll0, reg); 1278 1279 reg = regmap_read_4(sc->sc_anatop, pll0); 1280 reg |= CCM_FRAC_PLL_NEWDIV_VAL; 1281 regmap_write_4(sc->sc_anatop, pll0, reg); 1282 1283 for (i = 0; i < 5000; i++) { 1284 reg = regmap_read_4(sc->sc_anatop, pll0); 1285 if (reg & CCM_FRAC_PLL_BYPASS) 1286 break; 1287 if (reg & CCM_FRAC_PLL_POWERDOWN) 1288 break; 1289 if (reg & CCM_FRAC_PLL_NEWDIV_ACK) 1290 break; 1291 delay(10); 1292 } 1293 if (i == 5000) 1294 printf("%s: timeout\n", __func__); 1295 1296 reg = regmap_read_4(sc->sc_anatop, pll0); 1297 reg &= ~CCM_FRAC_PLL_NEWDIV_VAL; 1298 regmap_write_4(sc->sc_anatop, pll0, reg); 1299 1300 return 0; 1301 } 1302 1303 int 1304 imxccm_imx8m_set_div(struct imxccm_softc *sc, uint32_t idx, uint64_t freq, 1305 uint64_t parent_freq) 1306 { 1307 uint64_t div; 1308 uint32_t reg; 1309 1310 if (parent_freq < freq) { 1311 printf("%s: parent frequency too low (0x%08x)\n", 1312 __func__, idx); 1313 return -1; 1314 } 1315 1316 /* divisor can only be changed if enabled */ 1317 imxccm_enable(sc, &idx, 1); 1318 1319 div = 0; 1320 while (parent_freq / (div + 1) > freq) 1321 div++; 1322 reg = HREAD4(sc, sc->sc_divs[idx].reg); 1323 reg &= ~(sc->sc_divs[idx].mask << sc->sc_divs[idx].shift); 1324 reg |= (div << sc->sc_divs[idx].shift); 1325 HWRITE4(sc, sc->sc_divs[idx].reg, reg); 1326 HCLR4(sc, sc->sc_predivs[idx].reg, 1327 sc->sc_predivs[idx].mask << sc->sc_predivs[idx].shift); 1328 return 0; 1329 } 1330 1331 void 1332 imxccm_enable_parent(struct imxccm_softc *sc, uint32_t parent, int on) 1333 { 1334 if (on) 1335 imxccm_enable(sc, &parent, on); 1336 } 1337 1338 void 1339 imxccm_enable(void *cookie, uint32_t *cells, int on) 1340 { 1341 struct imxccm_softc *sc = cookie; 1342 uint32_t idx = cells[0], parent; 1343 uint32_t pcells[2]; 1344 uint16_t reg; 1345 uint8_t pos; 1346 1347 /* Dummy clock. */ 1348 if (idx == 0) 1349 return; 1350 1351 if (sc->sc_gates == imx8mm_gates) { 1352 switch (idx) { 1353 case IMX8MM_CLK_PCIE1_CTRL: 1354 case IMX8MM_CLK_PCIE2_CTRL: 1355 pcells[0] = sc->sc_phandle; 1356 pcells[1] = IMX8MM_SYS_PLL2_250M; 1357 imxccm_set_parent(cookie, &idx, pcells); 1358 break; 1359 case IMX8MM_CLK_PCIE1_PHY: 1360 case IMX8MM_CLK_PCIE2_PHY: 1361 pcells[0] = sc->sc_phandle; 1362 pcells[1] = IMX8MM_SYS_PLL2_100M; 1363 imxccm_set_parent(cookie, &idx, pcells); 1364 break; 1365 } 1366 } else if (sc->sc_gates == imx8mq_gates) { 1367 switch (idx) { 1368 case IMX8MQ_CLK_32K: 1369 /* always on */ 1370 return; 1371 case IMX8MQ_CLK_PCIE1_CTRL: 1372 case IMX8MQ_CLK_PCIE2_CTRL: 1373 pcells[0] = sc->sc_phandle; 1374 pcells[1] = IMX8MQ_SYS2_PLL_250M; 1375 imxccm_set_parent(cookie, &idx, pcells); 1376 break; 1377 case IMX8MQ_CLK_PCIE1_PHY: 1378 case IMX8MQ_CLK_PCIE2_PHY: 1379 pcells[0] = sc->sc_phandle; 1380 pcells[1] = IMX8MQ_SYS2_PLL_100M; 1381 imxccm_set_parent(cookie, &idx, pcells); 1382 break; 1383 } 1384 } else if (sc->sc_gates == imx7d_gates) { 1385 if (sc->sc_anatop == NULL) { 1386 sc->sc_anatop = regmap_bycompatible("fsl,imx7d-anatop"); 1387 KASSERT(sc->sc_anatop); 1388 } 1389 1390 switch (idx) { 1391 case IMX7D_PLL_ENET_MAIN_125M_CLK: 1392 regmap_write_4(sc->sc_anatop, CCM_ANALOG_PLL_ENET_SET, 1393 CCM_ANALOG_PLL_ENET_ENABLE_CLK_125MHZ); 1394 return; 1395 default: 1396 break; 1397 } 1398 } else if (sc->sc_gates == imx6_gates) { 1399 if (sc->sc_anatop == NULL) { 1400 sc->sc_anatop = regmap_bycompatible("fsl,imx6q-anatop"); 1401 KASSERT(sc->sc_anatop); 1402 } 1403 1404 switch (idx) { 1405 case IMX6_CLK_PLL3: 1406 imxccm_imx6_enable_pll_usb1(sc, on); 1407 return; 1408 case IMX6_CLK_PLL6: 1409 imxccm_imx6_enable_pll_enet(sc, on); 1410 return; 1411 case IMX6_CLK_PLL7: 1412 imxccm_imx6_enable_pll_usb2(sc, on); 1413 return; 1414 case IMX6_CLK_PLL3_USB_OTG: 1415 imxccm_enable_parent(sc, IMX6_CLK_PLL3, on); 1416 regmap_write_4(sc->sc_anatop, 1417 on ? CCM_ANALOG_PLL_USB1_SET : CCM_ANALOG_PLL_USB1_CLR, 1418 CCM_ANALOG_PLL_USB1_ENABLE); 1419 return; 1420 case IMX6_CLK_PLL6_ENET: 1421 imxccm_enable_parent(sc, IMX6_CLK_PLL6, on); 1422 regmap_write_4(sc->sc_anatop, 1423 on ? CCM_ANALOG_PLL_ENET_SET : CCM_ANALOG_PLL_ENET_CLR, 1424 CCM_ANALOG_PLL_ENET_ENABLE); 1425 return; 1426 case IMX6_CLK_PLL7_USB_HOST: 1427 imxccm_enable_parent(sc, IMX6_CLK_PLL7, on); 1428 regmap_write_4(sc->sc_anatop, 1429 on ? CCM_ANALOG_PLL_USB2_SET : CCM_ANALOG_PLL_USB2_CLR, 1430 CCM_ANALOG_PLL_USB2_ENABLE); 1431 return; 1432 case IMX6_CLK_USBPHY1: 1433 /* PLL outputs should always be on. */ 1434 regmap_write_4(sc->sc_anatop, CCM_ANALOG_PLL_USB1_SET, 1435 CCM_ANALOG_PLL_USB1_EN_USB_CLKS); 1436 imxccm_enable_parent(sc, IMX6_CLK_PLL3_USB_OTG, on); 1437 return; 1438 case IMX6_CLK_USBPHY2: 1439 /* PLL outputs should always be on. */ 1440 regmap_write_4(sc->sc_anatop, CCM_ANALOG_PLL_USB2_SET, 1441 CCM_ANALOG_PLL_USB2_EN_USB_CLKS); 1442 imxccm_enable_parent(sc, IMX6_CLK_PLL7_USB_HOST, on); 1443 return; 1444 case IMX6_CLK_SATA_REF_100: 1445 imxccm_enable_parent(sc, IMX6_CLK_PLL6_ENET, on); 1446 regmap_write_4(sc->sc_anatop, 1447 on ? CCM_ANALOG_PLL_ENET_SET : CCM_ANALOG_PLL_ENET_CLR, 1448 CCM_ANALOG_PLL_ENET_ENABLE_100M); 1449 return; 1450 case IMX6_CLK_ENET_REF: 1451 imxccm_enable_parent(sc, IMX6_CLK_PLL6_ENET, on); 1452 return; 1453 case IMX6_CLK_IPG: 1454 case IMX6_CLK_IPG_PER: 1455 case IMX6_CLK_ECSPI_ROOT: 1456 /* always on */ 1457 return; 1458 default: 1459 break; 1460 } 1461 } 1462 1463 if (on) { 1464 if (idx < sc->sc_ngates && sc->sc_gates[idx].parent) { 1465 parent = sc->sc_gates[idx].parent; 1466 imxccm_enable(sc, &parent, on); 1467 } 1468 1469 if (idx < sc->sc_ndivs && sc->sc_divs[idx].parent) { 1470 parent = sc->sc_divs[idx].parent; 1471 imxccm_enable(sc, &parent, on); 1472 } 1473 } 1474 1475 if (idx >= sc->sc_ngates || sc->sc_gates[idx].reg == 0) { 1476 if ((idx < sc->sc_ndivs && sc->sc_divs[idx].reg != 0) || 1477 (idx < sc->sc_nmuxs && sc->sc_muxs[idx].reg != 0)) 1478 return; 1479 printf("%s: 0x%08x\n", __func__, idx); 1480 return; 1481 } 1482 1483 reg = sc->sc_gates[idx].reg; 1484 pos = sc->sc_gates[idx].pos; 1485 1486 if (on) 1487 HSET4(sc, reg, 0x3 << (2 * pos)); 1488 else 1489 HCLR4(sc, reg, 0x3 << (2 * pos)); 1490 } 1491 1492 uint32_t 1493 imxccm_get_frequency(void *cookie, uint32_t *cells) 1494 { 1495 struct imxccm_softc *sc = cookie; 1496 uint32_t idx = cells[0]; 1497 uint32_t div, pre, reg, parent; 1498 uint32_t freq; 1499 1500 /* Dummy clock. */ 1501 if (idx == 0) 1502 return 0; 1503 1504 if (idx < sc->sc_ngates && sc->sc_gates[idx].parent) { 1505 parent = sc->sc_gates[idx].parent; 1506 return imxccm_get_frequency(sc, &parent); 1507 } 1508 1509 if (idx < sc->sc_ndivs && sc->sc_divs[idx].parent) { 1510 div = HREAD4(sc, sc->sc_divs[idx].reg); 1511 div = div >> sc->sc_divs[idx].shift; 1512 div = div & sc->sc_divs[idx].mask; 1513 parent = sc->sc_divs[idx].parent; 1514 return imxccm_get_frequency(sc, &parent) / (div + 1); 1515 } 1516 1517 if (sc->sc_gates == imx8mm_gates) { 1518 switch (idx) { 1519 case IMX8MM_CLK_ARM: 1520 parent = IMX8MM_ARM_PLL; 1521 return imxccm_get_frequency(sc, &parent); 1522 case IMX8MM_ARM_PLL: 1523 return imxccm_imx8mm_get_pll(sc, idx); 1524 } 1525 1526 /* These are composite clocks. */ 1527 if (idx < sc->sc_ngates && sc->sc_gates[idx].reg && 1528 idx < sc->sc_ndivs && sc->sc_divs[idx].reg && 1529 idx < sc->sc_npredivs && sc->sc_predivs[idx].reg) { 1530 switch (idx) { 1531 case IMX8MM_CLK_ENET_AXI: 1532 freq = imxccm_imx8mm_enet(sc, idx); 1533 break; 1534 case IMX8MM_CLK_AHB: 1535 freq = imxccm_imx8mm_ahb(sc, idx); 1536 break; 1537 case IMX8MM_CLK_I2C1: 1538 case IMX8MM_CLK_I2C2: 1539 case IMX8MM_CLK_I2C3: 1540 case IMX8MM_CLK_I2C4: 1541 freq = imxccm_imx8mm_i2c(sc, idx); 1542 break; 1543 case IMX8MM_CLK_UART1: 1544 case IMX8MM_CLK_UART2: 1545 case IMX8MM_CLK_UART3: 1546 case IMX8MM_CLK_UART4: 1547 freq = imxccm_imx8mm_uart(sc, idx); 1548 break; 1549 case IMX8MM_CLK_USDHC1: 1550 case IMX8MM_CLK_USDHC2: 1551 case IMX8MM_CLK_USDHC3: 1552 freq = imxccm_imx8mm_usdhc(sc, idx); 1553 break; 1554 default: 1555 printf("%s: 0x%08x\n", __func__, idx); 1556 return 0; 1557 } 1558 1559 reg = HREAD4(sc, sc->sc_divs[idx].reg); 1560 div = reg >> sc->sc_divs[idx].shift; 1561 div = div & sc->sc_divs[idx].mask; 1562 pre = reg >> sc->sc_predivs[idx].shift; 1563 pre = pre & sc->sc_predivs[idx].mask; 1564 return ((freq / (pre + 1)) / (div + 1)); 1565 } 1566 } else if (sc->sc_gates == imx8mp_gates) { 1567 /* These are composite clocks. */ 1568 if (idx < sc->sc_ngates && sc->sc_gates[idx].reg && 1569 idx < sc->sc_ndivs && sc->sc_divs[idx].reg && 1570 idx < sc->sc_npredivs && sc->sc_predivs[idx].reg) { 1571 switch (idx) { 1572 case IMX8MP_CLK_ENET_AXI: 1573 freq = imxccm_imx8mm_enet(sc, idx); 1574 break; 1575 case IMX8MP_CLK_AHB: 1576 freq = imxccm_imx8mm_ahb(sc, idx); 1577 break; 1578 case IMX8MP_CLK_I2C1: 1579 case IMX8MP_CLK_I2C2: 1580 case IMX8MP_CLK_I2C3: 1581 case IMX8MP_CLK_I2C4: 1582 case IMX8MP_CLK_I2C5: 1583 case IMX8MP_CLK_I2C6: 1584 freq = imxccm_imx8mm_i2c(sc, idx); 1585 break; 1586 case IMX8MP_CLK_UART1: 1587 case IMX8MP_CLK_UART2: 1588 case IMX8MP_CLK_UART3: 1589 case IMX8MP_CLK_UART4: 1590 freq = imxccm_imx8mm_uart(sc, idx); 1591 break; 1592 case IMX8MP_CLK_USDHC1: 1593 case IMX8MP_CLK_USDHC2: 1594 case IMX8MP_CLK_USDHC3: 1595 freq = imxccm_imx8mm_usdhc(sc, idx); 1596 break; 1597 case IMX8MP_CLK_ENET_QOS: 1598 freq = imxccm_imx8mp_enet_qos(sc, idx); 1599 break; 1600 case IMX8MP_CLK_ENET_QOS_TIMER: 1601 freq = imxccm_imx8mp_enet_qos_timer(sc, idx); 1602 break; 1603 case IMX8MP_CLK_HSIO_AXI: 1604 freq = imxccm_imx8mp_hsio_axi(sc, idx); 1605 break; 1606 default: 1607 printf("%s: 0x%08x\n", __func__, idx); 1608 return 0; 1609 } 1610 1611 reg = HREAD4(sc, sc->sc_divs[idx].reg); 1612 div = reg >> sc->sc_divs[idx].shift; 1613 div = div & sc->sc_divs[idx].mask; 1614 pre = reg >> sc->sc_predivs[idx].shift; 1615 pre = pre & sc->sc_predivs[idx].mask; 1616 return ((freq / (pre + 1)) / (div + 1)); 1617 } 1618 } else if (sc->sc_gates == imx8mq_gates) { 1619 switch (idx) { 1620 case IMX8MQ_CLK_ARM: 1621 parent = IMX8MQ_ARM_PLL; 1622 return imxccm_get_frequency(sc, &parent); 1623 case IMX8MQ_ARM_PLL: 1624 return imxccm_imx8mq_get_pll(sc, idx); 1625 } 1626 1627 /* These are composite clocks. */ 1628 if (idx < sc->sc_ngates && sc->sc_gates[idx].reg && 1629 idx < sc->sc_ndivs && sc->sc_divs[idx].reg && 1630 idx < sc->sc_npredivs && sc->sc_predivs[idx].reg) { 1631 switch (idx) { 1632 case IMX8MQ_CLK_ENET_AXI: 1633 freq = imxccm_imx8mq_enet(sc, idx); 1634 break; 1635 case IMX8MQ_CLK_AHB: 1636 freq = imxccm_imx8mq_ahb(sc, idx); 1637 break; 1638 case IMX8MQ_CLK_I2C1: 1639 case IMX8MQ_CLK_I2C2: 1640 case IMX8MQ_CLK_I2C3: 1641 case IMX8MQ_CLK_I2C4: 1642 freq = imxccm_imx8mq_i2c(sc, idx); 1643 break; 1644 case IMX8MQ_CLK_UART1: 1645 case IMX8MQ_CLK_UART2: 1646 case IMX8MQ_CLK_UART3: 1647 case IMX8MQ_CLK_UART4: 1648 freq = imxccm_imx8mq_uart(sc, idx); 1649 break; 1650 case IMX8MQ_CLK_USDHC1: 1651 case IMX8MQ_CLK_USDHC2: 1652 freq = imxccm_imx8mq_usdhc(sc, idx); 1653 break; 1654 case IMX8MQ_CLK_USB_BUS: 1655 case IMX8MQ_CLK_USB_CORE_REF: 1656 case IMX8MQ_CLK_USB_PHY_REF: 1657 freq = imxccm_imx8mq_usb(sc, idx); 1658 break; 1659 case IMX8MQ_CLK_ECSPI1: 1660 case IMX8MQ_CLK_ECSPI2: 1661 case IMX8MQ_CLK_ECSPI3: 1662 freq = imxccm_imx8mq_ecspi(sc, idx); 1663 break; 1664 case IMX8MQ_CLK_PWM1: 1665 case IMX8MQ_CLK_PWM2: 1666 case IMX8MQ_CLK_PWM3: 1667 case IMX8MQ_CLK_PWM4: 1668 freq = imxccm_imx8mq_pwm(sc, idx); 1669 break; 1670 default: 1671 printf("%s: 0x%08x\n", __func__, idx); 1672 return 0; 1673 } 1674 1675 reg = HREAD4(sc, sc->sc_divs[idx].reg); 1676 div = reg >> sc->sc_divs[idx].shift; 1677 div = div & sc->sc_divs[idx].mask; 1678 pre = reg >> sc->sc_predivs[idx].shift; 1679 pre = pre & sc->sc_predivs[idx].mask; 1680 return ((freq / (pre + 1)) / (div + 1)); 1681 } 1682 1683 } else if (sc->sc_gates == imx7d_gates) { 1684 switch (idx) { 1685 case IMX7D_ENET_AXI_ROOT_SRC: 1686 return imxccm_imx7d_enet(sc, idx); 1687 case IMX7D_I2C1_ROOT_SRC: 1688 case IMX7D_I2C2_ROOT_SRC: 1689 case IMX7D_I2C3_ROOT_SRC: 1690 case IMX7D_I2C4_ROOT_SRC: 1691 return imxccm_imx7d_i2c(sc, idx); 1692 case IMX7D_UART1_ROOT_SRC: 1693 case IMX7D_UART2_ROOT_SRC: 1694 case IMX7D_UART3_ROOT_SRC: 1695 case IMX7D_UART4_ROOT_SRC: 1696 case IMX7D_UART5_ROOT_SRC: 1697 case IMX7D_UART6_ROOT_SRC: 1698 case IMX7D_UART7_ROOT_SRC: 1699 return imxccm_imx7d_uart(sc, idx); 1700 case IMX7D_USDHC1_ROOT_SRC: 1701 case IMX7D_USDHC2_ROOT_SRC: 1702 case IMX7D_USDHC3_ROOT_SRC: 1703 return imxccm_imx7d_usdhc(sc, idx); 1704 } 1705 } else if (sc->sc_gates == imx6ul_gates) { 1706 switch (idx) { 1707 case IMX6UL_CLK_ARM: 1708 return imxccm_get_armclk(sc); 1709 case IMX6UL_CLK_IPG: 1710 return imxccm_get_ipgclk(sc); 1711 case IMX6UL_CLK_PERCLK: 1712 return imxccm_get_ipg_perclk(sc); 1713 case IMX6UL_CLK_UART1_SERIAL: 1714 return imxccm_get_uartclk(sc); 1715 case IMX6UL_CLK_USDHC1: 1716 case IMX6UL_CLK_USDHC2: 1717 return imxccm_get_usdhx(sc, idx - IMX6UL_CLK_USDHC1 + 1); 1718 } 1719 } else if (sc->sc_gates == imx6_gates) { 1720 switch (idx) { 1721 case IMX6_CLK_AHB: 1722 return imxccm_get_ahbclk(sc); 1723 case IMX6_CLK_ARM: 1724 return imxccm_get_armclk(sc); 1725 case IMX6_CLK_IPG: 1726 return imxccm_get_ipgclk(sc); 1727 case IMX6_CLK_IPG_PER: 1728 return imxccm_get_ipg_perclk(sc); 1729 case IMX6_CLK_ECSPI_ROOT: 1730 return imxccm_get_ecspiclk(sc); 1731 case IMX6_CLK_UART_SERIAL: 1732 return imxccm_get_uartclk(sc); 1733 case IMX6_CLK_USDHC1: 1734 case IMX6_CLK_USDHC2: 1735 case IMX6_CLK_USDHC3: 1736 case IMX6_CLK_USDHC4: 1737 return imxccm_get_usdhx(sc, idx - IMX6_CLK_USDHC1 + 1); 1738 } 1739 } 1740 1741 printf("%s: 0x%08x\n", __func__, idx); 1742 return 0; 1743 } 1744 1745 int 1746 imxccm_set_frequency(void *cookie, uint32_t *cells, uint32_t freq) 1747 { 1748 struct imxccm_softc *sc = cookie; 1749 uint32_t idx = cells[0]; 1750 uint32_t reg, div, parent, parent_freq; 1751 uint32_t pcells[2]; 1752 int ret; 1753 1754 if (sc->sc_divs == imx8mm_divs) { 1755 switch (idx) { 1756 case IMX8MM_CLK_ARM: 1757 parent = IMX8MM_CLK_A53_SRC; 1758 return imxccm_set_frequency(cookie, &parent, freq); 1759 case IMX8MM_CLK_A53_SRC: 1760 pcells[0] = sc->sc_phandle; 1761 pcells[1] = IMX8MM_SYS_PLL1_800M; 1762 ret = imxccm_set_parent(cookie, &idx, pcells); 1763 if (ret) 1764 return ret; 1765 ret = imxccm_imx8mm_set_pll(sc, IMX8MM_ARM_PLL, freq); 1766 pcells[0] = sc->sc_phandle; 1767 pcells[1] = IMX8MM_ARM_PLL_OUT; 1768 imxccm_set_parent(cookie, &idx, pcells); 1769 return ret; 1770 case IMX8MM_CLK_USDHC1_ROOT: 1771 case IMX8MM_CLK_USDHC2_ROOT: 1772 case IMX8MM_CLK_USDHC3_ROOT: 1773 parent = sc->sc_gates[idx].parent; 1774 return imxccm_set_frequency(sc, &parent, freq); 1775 case IMX8MM_CLK_USDHC1: 1776 case IMX8MM_CLK_USDHC2: 1777 case IMX8MM_CLK_USDHC3: 1778 parent_freq = imxccm_imx8mm_usdhc(sc, idx); 1779 return imxccm_imx8m_set_div(sc, idx, freq, parent_freq); 1780 } 1781 } else if (sc->sc_divs == imx8mp_divs) { 1782 switch (idx) { 1783 case IMX8MP_CLK_ENET_QOS: 1784 parent_freq = imxccm_imx8mp_enet_qos(sc, idx); 1785 return imxccm_imx8m_set_div(sc, idx, freq, parent_freq); 1786 case IMX8MP_CLK_ENET_QOS_TIMER: 1787 parent_freq = imxccm_imx8mp_enet_qos_timer(sc, idx); 1788 return imxccm_imx8m_set_div(sc, idx, freq, parent_freq); 1789 case IMX8MP_CLK_HSIO_AXI: 1790 parent_freq = imxccm_imx8mp_hsio_axi(sc, idx); 1791 return imxccm_imx8m_set_div(sc, idx, freq, parent_freq); 1792 } 1793 } else if (sc->sc_divs == imx8mq_divs) { 1794 switch (idx) { 1795 case IMX8MQ_CLK_ARM: 1796 parent = IMX8MQ_CLK_A53_SRC; 1797 return imxccm_set_frequency(cookie, &parent, freq); 1798 case IMX8MQ_CLK_A53_SRC: 1799 pcells[0] = sc->sc_phandle; 1800 pcells[1] = IMX8MQ_SYS1_PLL_800M; 1801 ret = imxccm_set_parent(cookie, &idx, pcells); 1802 if (ret) 1803 return ret; 1804 ret = imxccm_imx8mq_set_pll(sc, IMX8MQ_ARM_PLL, freq); 1805 pcells[0] = sc->sc_phandle; 1806 pcells[1] = IMX8MQ_ARM_PLL_OUT; 1807 imxccm_set_parent(cookie, &idx, pcells); 1808 return ret; 1809 case IMX8MQ_CLK_USB_BUS: 1810 case IMX8MQ_CLK_USB_CORE_REF: 1811 case IMX8MQ_CLK_USB_PHY_REF: 1812 if (imxccm_get_frequency(sc, cells) != freq) 1813 break; 1814 return 0; 1815 case IMX8MQ_CLK_USDHC1: 1816 case IMX8MQ_CLK_USDHC2: 1817 parent_freq = imxccm_imx8mq_usdhc(sc, idx); 1818 return imxccm_imx8m_set_div(sc, idx, freq, parent_freq); 1819 } 1820 } else if (sc->sc_divs == imx7d_divs) { 1821 switch (idx) { 1822 case IMX7D_USDHC1_ROOT_CLK: 1823 case IMX7D_USDHC2_ROOT_CLK: 1824 case IMX7D_USDHC3_ROOT_CLK: 1825 parent = sc->sc_gates[idx].parent; 1826 return imxccm_set_frequency(sc, &parent, freq); 1827 case IMX7D_USDHC1_ROOT_DIV: 1828 case IMX7D_USDHC2_ROOT_DIV: 1829 case IMX7D_USDHC3_ROOT_DIV: 1830 parent = sc->sc_divs[idx].parent; 1831 parent_freq = imxccm_get_frequency(sc, &parent); 1832 div = 0; 1833 while (parent_freq / (div + 1) > freq) 1834 div++; 1835 reg = HREAD4(sc, sc->sc_divs[idx].reg); 1836 reg &= ~(sc->sc_divs[idx].mask << sc->sc_divs[idx].shift); 1837 reg |= (div << sc->sc_divs[idx].shift); 1838 HWRITE4(sc, sc->sc_divs[idx].reg, reg); 1839 return 0; 1840 } 1841 } 1842 1843 printf("%s: 0x%08x %x\n", __func__, idx, freq); 1844 return -1; 1845 } 1846 1847 int 1848 imxccm_set_parent(void *cookie, uint32_t *cells, uint32_t *pcells) 1849 { 1850 struct imxccm_softc *sc = cookie; 1851 uint32_t idx = cells[0]; 1852 uint32_t pidx; 1853 uint32_t mux; 1854 1855 if (pcells[0] != sc->sc_phandle) { 1856 printf("%s: 0x%08x parent 0x%08x\n", __func__, idx, pcells[0]); 1857 return -1; 1858 } 1859 1860 pidx = pcells[1]; 1861 1862 if (sc->sc_muxs == imx8mm_muxs) { 1863 switch (idx) { 1864 case IMX8MM_CLK_A53_SRC: 1865 if (pidx != IMX8MM_ARM_PLL_OUT && 1866 pidx != IMX8MM_SYS_PLL1_800M) 1867 break; 1868 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 1869 mux &= ~(sc->sc_muxs[idx].mask << sc->sc_muxs[idx].shift); 1870 if (pidx == IMX8MM_ARM_PLL_OUT) 1871 mux |= (0x1 << sc->sc_muxs[idx].shift); 1872 if (pidx == IMX8MM_SYS_PLL1_800M) 1873 mux |= (0x4 << sc->sc_muxs[idx].shift); 1874 HWRITE4(sc, sc->sc_muxs[idx].reg, mux); 1875 return 0; 1876 case IMX8MM_CLK_USB_BUS: 1877 if (pidx != IMX8MM_SYS_PLL2_500M) 1878 break; 1879 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 1880 mux &= ~(sc->sc_muxs[idx].mask << sc->sc_muxs[idx].shift); 1881 mux |= (0x1 << sc->sc_muxs[idx].shift); 1882 HWRITE4(sc, sc->sc_muxs[idx].reg, mux); 1883 return 0; 1884 case IMX8MM_CLK_USB_CORE_REF: 1885 case IMX8MM_CLK_USB_PHY_REF: 1886 if (pidx != IMX8MM_SYS_PLL1_100M) 1887 break; 1888 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 1889 mux &= ~(sc->sc_muxs[idx].mask << sc->sc_muxs[idx].shift); 1890 mux |= (0x1 << sc->sc_muxs[idx].shift); 1891 HWRITE4(sc, sc->sc_muxs[idx].reg, mux); 1892 return 0; 1893 case IMX8MM_CLK_PCIE1_CTRL: 1894 case IMX8MM_CLK_PCIE2_CTRL: 1895 if (pidx != IMX8MM_SYS_PLL2_250M) 1896 break; 1897 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 1898 mux &= ~(sc->sc_muxs[idx].mask << sc->sc_muxs[idx].shift); 1899 mux |= (0x1 << sc->sc_muxs[idx].shift); 1900 HWRITE4(sc, sc->sc_muxs[idx].reg, mux); 1901 return 0; 1902 case IMX8MM_CLK_PCIE1_PHY: 1903 case IMX8MM_CLK_PCIE2_PHY: 1904 if (pidx != IMX8MM_SYS_PLL2_100M) 1905 break; 1906 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 1907 mux &= ~(sc->sc_muxs[idx].mask << sc->sc_muxs[idx].shift); 1908 mux |= (0x1 << sc->sc_muxs[idx].shift); 1909 HWRITE4(sc, sc->sc_muxs[idx].reg, mux); 1910 return 0; 1911 } 1912 } else if (sc->sc_muxs == imx8mp_muxs) { 1913 switch (idx) { 1914 case IMX8MP_CLK_ENET_AXI: 1915 if (pidx != IMX8MP_SYS_PLL1_266M) 1916 break; 1917 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 1918 mux &= ~(sc->sc_muxs[idx].mask << sc->sc_muxs[idx].shift); 1919 mux |= (0x1 << sc->sc_muxs[idx].shift); 1920 HWRITE4(sc, sc->sc_muxs[idx].reg, mux); 1921 return 0; 1922 case IMX8MP_CLK_PCIE_PHY: 1923 if (pidx != IMX8MP_CLK_24M) 1924 break; 1925 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 1926 mux &= ~(sc->sc_muxs[idx].mask << sc->sc_muxs[idx].shift); 1927 mux |= (0x0 << sc->sc_muxs[idx].shift); 1928 HWRITE4(sc, sc->sc_muxs[idx].reg, mux); 1929 return 0; 1930 case IMX8MP_CLK_PCIE_AUX: 1931 if (pidx != IMX8MP_SYS_PLL2_50M) 1932 break; 1933 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 1934 mux &= ~(sc->sc_muxs[idx].mask << sc->sc_muxs[idx].shift); 1935 mux |= (0x2 << sc->sc_muxs[idx].shift); 1936 HWRITE4(sc, sc->sc_muxs[idx].reg, mux); 1937 return 0; 1938 case IMX8MP_CLK_ENET_QOS: 1939 if (pidx != IMX8MP_SYS_PLL2_125M) 1940 break; 1941 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 1942 mux &= ~(sc->sc_muxs[idx].mask << sc->sc_muxs[idx].shift); 1943 mux |= (0x1 << sc->sc_muxs[idx].shift); 1944 HWRITE4(sc, sc->sc_muxs[idx].reg, mux); 1945 return 0; 1946 case IMX8MP_CLK_ENET_QOS_TIMER: 1947 if (pidx != IMX8MP_SYS_PLL2_100M) 1948 break; 1949 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 1950 mux &= ~(sc->sc_muxs[idx].mask << sc->sc_muxs[idx].shift); 1951 mux |= (0x1 << sc->sc_muxs[idx].shift); 1952 HWRITE4(sc, sc->sc_muxs[idx].reg, mux); 1953 return 0; 1954 case IMX8MP_CLK_USB_PHY_REF: 1955 if (pidx != IMX8MP_CLK_24M) 1956 break; 1957 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 1958 mux &= ~(sc->sc_muxs[idx].mask << sc->sc_muxs[idx].shift); 1959 mux |= (0x0 << sc->sc_muxs[idx].shift); 1960 HWRITE4(sc, sc->sc_muxs[idx].reg, mux); 1961 return 0; 1962 case IMX8MP_CLK_HSIO_AXI: 1963 if (pidx != IMX8MP_SYS_PLL2_500M) 1964 break; 1965 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 1966 mux &= ~(sc->sc_muxs[idx].mask << sc->sc_muxs[idx].shift); 1967 mux |= (0x1 << sc->sc_muxs[idx].shift); 1968 HWRITE4(sc, sc->sc_muxs[idx].reg, mux); 1969 return 0; 1970 } 1971 } else if (sc->sc_muxs == imx8mq_muxs) { 1972 switch (idx) { 1973 case IMX8MQ_CLK_A53_SRC: 1974 if (pidx != IMX8MQ_ARM_PLL_OUT && 1975 pidx != IMX8MQ_SYS1_PLL_800M) 1976 break; 1977 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 1978 mux &= ~(sc->sc_muxs[idx].mask << sc->sc_muxs[idx].shift); 1979 if (pidx == IMX8MQ_ARM_PLL_OUT) 1980 mux |= (0x1 << sc->sc_muxs[idx].shift); 1981 if (pidx == IMX8MQ_SYS1_PLL_800M) 1982 mux |= (0x4 << sc->sc_muxs[idx].shift); 1983 HWRITE4(sc, sc->sc_muxs[idx].reg, mux); 1984 return 0; 1985 case IMX8MQ_CLK_USB_BUS: 1986 if (pidx != IMX8MQ_SYS2_PLL_500M) 1987 break; 1988 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 1989 mux &= ~(sc->sc_muxs[idx].mask << sc->sc_muxs[idx].shift); 1990 mux |= (0x1 << sc->sc_muxs[idx].shift); 1991 HWRITE4(sc, sc->sc_muxs[idx].reg, mux); 1992 return 0; 1993 case IMX8MQ_CLK_USB_CORE_REF: 1994 case IMX8MQ_CLK_USB_PHY_REF: 1995 if (pidx != IMX8MQ_SYS1_PLL_100M) 1996 break; 1997 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 1998 mux &= ~(sc->sc_muxs[idx].mask << sc->sc_muxs[idx].shift); 1999 mux |= (0x1 << sc->sc_muxs[idx].shift); 2000 HWRITE4(sc, sc->sc_muxs[idx].reg, mux); 2001 return 0; 2002 case IMX8MQ_CLK_PCIE1_CTRL: 2003 case IMX8MQ_CLK_PCIE2_CTRL: 2004 if (pidx != IMX8MQ_SYS2_PLL_250M) 2005 break; 2006 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 2007 mux &= ~(sc->sc_muxs[idx].mask << sc->sc_muxs[idx].shift); 2008 mux |= (0x1 << sc->sc_muxs[idx].shift); 2009 HWRITE4(sc, sc->sc_muxs[idx].reg, mux); 2010 return 0; 2011 case IMX8MQ_CLK_PCIE1_PHY: 2012 case IMX8MQ_CLK_PCIE2_PHY: 2013 if (pidx != IMX8MQ_SYS2_PLL_100M) 2014 break; 2015 mux = HREAD4(sc, sc->sc_muxs[idx].reg); 2016 mux &= ~(sc->sc_muxs[idx].mask << sc->sc_muxs[idx].shift); 2017 mux |= (0x1 << sc->sc_muxs[idx].shift); 2018 HWRITE4(sc, sc->sc_muxs[idx].reg, mux); 2019 return 0; 2020 } 2021 } 2022 2023 printf("%s: 0x%08x 0x%08x\n", __func__, idx, pidx); 2024 return -1; 2025 } 2026