1 /* 2 * (C) Copyright 2017 Rockchip Electronics Co., Ltd 3 * Author: Andy Yan <andy.yan@rock-chips.com> 4 * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH 5 * SPDX-License-Identifier: GPL-2.0 6 */ 7 8 #include <common.h> 9 #include <clk-uclass.h> 10 #include <dm.h> 11 #include <dt-structs.h> 12 #include <errno.h> 13 #include <mapmem.h> 14 #include <syscon.h> 15 #include <asm/arch/clock.h> 16 #include <asm/arch/cru_rk3368.h> 17 #include <asm/arch/hardware.h> 18 #include <asm/io.h> 19 #include <dm/lists.h> 20 #include <dt-bindings/clock/rk3368-cru.h> 21 22 DECLARE_GLOBAL_DATA_PTR; 23 24 #if CONFIG_IS_ENABLED(OF_PLATDATA) 25 struct rk3368_clk_plat { 26 struct dtd_rockchip_rk3368_cru dtd; 27 }; 28 #endif 29 30 struct pll_div { 31 u32 nr; 32 u32 nf; 33 u32 no; 34 }; 35 36 #define OSC_HZ (24 * 1000 * 1000) 37 #define APLL_L_HZ (800 * 1000 * 1000) 38 #define APLL_B_HZ (816 * 1000 * 1000) 39 #define GPLL_HZ (576 * 1000 * 1000) 40 #define CPLL_HZ (400 * 1000 * 1000) 41 42 #define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1)) 43 44 #define PLL_DIVISORS(hz, _nr, _no) { \ 45 .nr = _nr, .nf = (u32)((u64)hz * _nr * _no / OSC_HZ), .no = _no}; \ 46 _Static_assert(((u64)hz * _nr * _no / OSC_HZ) * OSC_HZ /\ 47 (_nr * _no) == hz, #hz "Hz cannot be hit with PLL " \ 48 "divisors on line " __stringify(__LINE__)); 49 50 #if IS_ENABLED(CONFIG_SPL_BUILD) || IS_ENABLED(CONFIG_TPL_BUILD) 51 static const struct pll_div apll_l_init_cfg = PLL_DIVISORS(APLL_L_HZ, 12, 2); 52 static const struct pll_div apll_b_init_cfg = PLL_DIVISORS(APLL_B_HZ, 1, 2); 53 #if !defined(CONFIG_TPL_BUILD) 54 static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 1, 2); 55 static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 6); 56 #endif 57 #endif 58 59 static ulong rk3368_clk_get_rate(struct clk *clk); 60 61 /* Get pll rate by id */ 62 static uint32_t rkclk_pll_get_rate(struct rk3368_cru *cru, 63 enum rk3368_pll_id pll_id) 64 { 65 uint32_t nr, no, nf; 66 uint32_t con; 67 struct rk3368_pll *pll = &cru->pll[pll_id]; 68 69 con = readl(&pll->con3); 70 71 switch ((con & PLL_MODE_MASK) >> PLL_MODE_SHIFT) { 72 case PLL_MODE_SLOW: 73 return OSC_HZ; 74 case PLL_MODE_NORMAL: 75 con = readl(&pll->con0); 76 no = ((con & PLL_OD_MASK) >> PLL_OD_SHIFT) + 1; 77 nr = ((con & PLL_NR_MASK) >> PLL_NR_SHIFT) + 1; 78 con = readl(&pll->con1); 79 nf = ((con & PLL_NF_MASK) >> PLL_NF_SHIFT) + 1; 80 81 return (24 * nf / (nr * no)) * 1000000; 82 case PLL_MODE_DEEP_SLOW: 83 default: 84 return 32768; 85 } 86 } 87 88 #if IS_ENABLED(CONFIG_SPL_BUILD) || IS_ENABLED(CONFIG_TPL_BUILD) 89 static int rkclk_set_pll(struct rk3368_cru *cru, enum rk3368_pll_id pll_id, 90 const struct pll_div *div) 91 { 92 struct rk3368_pll *pll = &cru->pll[pll_id]; 93 /* All PLLs have same VCO and output frequency range restrictions*/ 94 uint vco_hz = OSC_HZ / 1000 * div->nf / div->nr * 1000; 95 uint output_hz = vco_hz / div->no; 96 97 debug("PLL at %p: nf=%d, nr=%d, no=%d, vco=%u Hz, output=%u Hz\n", 98 pll, div->nf, div->nr, div->no, vco_hz, output_hz); 99 100 /* enter slow mode and reset pll */ 101 rk_clrsetreg(&pll->con3, PLL_MODE_MASK | PLL_RESET_MASK, 102 PLL_RESET << PLL_RESET_SHIFT); 103 104 rk_clrsetreg(&pll->con0, PLL_NR_MASK | PLL_OD_MASK, 105 ((div->nr - 1) << PLL_NR_SHIFT) | 106 ((div->no - 1) << PLL_OD_SHIFT)); 107 writel((div->nf - 1) << PLL_NF_SHIFT, &pll->con1); 108 /* 109 * BWADJ should be set to NF / 2 to ensure the nominal bandwidth. 110 * Compare the RK3368 TRM, section "3.6.4 PLL Bandwidth Adjustment". 111 */ 112 clrsetbits_le32(&pll->con2, PLL_BWADJ_MASK, (div->nf >> 1) - 1); 113 114 udelay(10); 115 116 /* return from reset */ 117 rk_clrreg(&pll->con3, PLL_RESET_MASK); 118 119 /* waiting for pll lock */ 120 while (!(readl(&pll->con1) & PLL_LOCK_STA)) 121 udelay(1); 122 123 rk_clrsetreg(&pll->con3, PLL_MODE_MASK, 124 PLL_MODE_NORMAL << PLL_MODE_SHIFT); 125 126 return 0; 127 } 128 #endif 129 130 #if IS_ENABLED(CONFIG_SPL_BUILD) || IS_ENABLED(CONFIG_TPL_BUILD) 131 static void rkclk_init(struct rk3368_cru *cru) 132 { 133 u32 apllb, aplll, dpll, cpll, gpll; 134 135 rkclk_set_pll(cru, APLLB, &apll_b_init_cfg); 136 rkclk_set_pll(cru, APLLL, &apll_l_init_cfg); 137 #if !defined(CONFIG_TPL_BUILD) 138 /* 139 * If we plan to return to the boot ROM, we can't increase the 140 * GPLL rate from the SPL stage. 141 */ 142 rkclk_set_pll(cru, GPLL, &gpll_init_cfg); 143 rkclk_set_pll(cru, CPLL, &cpll_init_cfg); 144 #endif 145 146 apllb = rkclk_pll_get_rate(cru, APLLB); 147 aplll = rkclk_pll_get_rate(cru, APLLL); 148 dpll = rkclk_pll_get_rate(cru, DPLL); 149 cpll = rkclk_pll_get_rate(cru, CPLL); 150 gpll = rkclk_pll_get_rate(cru, GPLL); 151 152 debug("%s apllb(%d) apll(%d) dpll(%d) cpll(%d) gpll(%d)\n", 153 __func__, apllb, aplll, dpll, cpll, gpll); 154 } 155 #endif 156 157 #if !IS_ENABLED(CONFIG_SPL_BUILD) || CONFIG_IS_ENABLED(MMC_SUPPORT) 158 static ulong rk3368_mmc_get_clk(struct rk3368_cru *cru, uint clk_id) 159 { 160 u32 div, con, con_id, rate; 161 u32 pll_rate; 162 163 switch (clk_id) { 164 case HCLK_SDMMC: 165 con_id = 50; 166 break; 167 case HCLK_EMMC: 168 con_id = 51; 169 break; 170 case SCLK_SDIO0: 171 con_id = 48; 172 break; 173 default: 174 return -EINVAL; 175 } 176 177 con = readl(&cru->clksel_con[con_id]); 178 switch (con & MMC_PLL_SEL_MASK) { 179 case MMC_PLL_SEL_GPLL: 180 pll_rate = rkclk_pll_get_rate(cru, GPLL); 181 break; 182 case MMC_PLL_SEL_24M: 183 pll_rate = OSC_HZ; 184 break; 185 case MMC_PLL_SEL_CPLL: 186 pll_rate = rkclk_pll_get_rate(cru, CPLL); 187 break; 188 case MMC_PLL_SEL_USBPHY_480M: 189 default: 190 return -EINVAL; 191 } 192 div = (con & MMC_CLK_DIV_MASK) >> MMC_CLK_DIV_SHIFT; 193 rate = DIV_TO_RATE(pll_rate, div); 194 195 debug("%s: raw rate %d (post-divide by 2)\n", __func__, rate); 196 return rate >> 1; 197 } 198 199 static ulong rk3368_mmc_find_best_rate_and_parent(struct clk *clk, 200 ulong rate, 201 u32 *best_mux, 202 u32 *best_div) 203 { 204 int i; 205 ulong best_rate = 0; 206 const ulong MHz = 1000000; 207 const struct { 208 u32 mux; 209 ulong rate; 210 } parents[] = { 211 { .mux = MMC_PLL_SEL_CPLL, .rate = CPLL_HZ }, 212 { .mux = MMC_PLL_SEL_GPLL, .rate = GPLL_HZ }, 213 { .mux = MMC_PLL_SEL_24M, .rate = 24 * MHz } 214 }; 215 216 debug("%s: target rate %ld\n", __func__, rate); 217 for (i = 0; i < ARRAY_SIZE(parents); ++i) { 218 /* 219 * Find the largest rate no larger than the target-rate for 220 * the current parent. 221 */ 222 ulong parent_rate = parents[i].rate; 223 u32 div = DIV_ROUND_UP(parent_rate, rate); 224 u32 adj_div = div; 225 ulong new_rate = parent_rate / adj_div; 226 227 debug("%s: rate %ld, parent-mux %d, parent-rate %ld, div %d\n", 228 __func__, rate, parents[i].mux, parents[i].rate, div); 229 230 /* Skip, if not representable */ 231 if ((div - 1) > MMC_CLK_DIV_MASK) 232 continue; 233 234 /* Skip, if we already have a better (or equal) solution */ 235 if (new_rate <= best_rate) 236 continue; 237 238 /* This is our new best rate. */ 239 best_rate = new_rate; 240 *best_mux = parents[i].mux; 241 *best_div = div - 1; 242 } 243 244 debug("%s: best_mux = %x, best_div = %d, best_rate = %ld\n", 245 __func__, *best_mux, *best_div, best_rate); 246 247 return best_rate; 248 } 249 250 static ulong rk3368_mmc_set_clk(struct clk *clk, ulong rate) 251 { 252 struct rk3368_clk_priv *priv = dev_get_priv(clk->dev); 253 struct rk3368_cru *cru = priv->cru; 254 ulong clk_id = clk->id; 255 u32 con_id, mux = 0, div = 0; 256 257 /* Find the best parent and rate */ 258 rk3368_mmc_find_best_rate_and_parent(clk, rate << 1, &mux, &div); 259 260 switch (clk_id) { 261 case HCLK_SDMMC: 262 con_id = 50; 263 break; 264 case HCLK_EMMC: 265 con_id = 51; 266 break; 267 case SCLK_SDIO0: 268 con_id = 48; 269 break; 270 default: 271 return -EINVAL; 272 } 273 274 rk_clrsetreg(&cru->clksel_con[con_id], 275 MMC_PLL_SEL_MASK | MMC_CLK_DIV_MASK, 276 mux | div); 277 278 return rk3368_mmc_get_clk(cru, clk_id); 279 } 280 #endif 281 282 #if IS_ENABLED(CONFIG_TPL_BUILD) 283 static ulong rk3368_ddr_set_clk(struct rk3368_cru *cru, ulong set_rate) 284 { 285 const struct pll_div *dpll_cfg = NULL; 286 const ulong MHz = 1000000; 287 288 /* Fout = ((Fin /NR) * NF )/ NO */ 289 static const struct pll_div dpll_1200 = PLL_DIVISORS(1200 * MHz, 1, 1); 290 static const struct pll_div dpll_1332 = PLL_DIVISORS(1332 * MHz, 2, 1); 291 static const struct pll_div dpll_1600 = PLL_DIVISORS(1600 * MHz, 3, 2); 292 293 switch (set_rate) { 294 case 1200*MHz: 295 dpll_cfg = &dpll_1200; 296 break; 297 case 1332*MHz: 298 dpll_cfg = &dpll_1332; 299 break; 300 case 1600*MHz: 301 dpll_cfg = &dpll_1600; 302 break; 303 default: 304 error("Unsupported SDRAM frequency!,%ld\n", set_rate); 305 } 306 rkclk_set_pll(cru, DPLL, dpll_cfg); 307 308 return set_rate; 309 } 310 #endif 311 312 #if CONFIG_IS_ENABLED(GMAC_ROCKCHIP) 313 static ulong rk3368_gmac_set_clk(struct rk3368_cru *cru, 314 ulong clk_id, ulong set_rate) 315 { 316 /* 317 * This models the 'assigned-clock-parents = <&ext_gmac>' from 318 * the DTS and switches to the 'ext_gmac' clock parent. 319 */ 320 rk_setreg(&cru->clksel_con[43], GMAC_MUX_SEL_EXTCLK); 321 return set_rate; 322 } 323 #endif 324 325 /* 326 * RK3368 SPI clocks have a common divider-width (7 bits) and a single bit 327 * to select either CPLL or GPLL as the clock-parent. The location within 328 * the enclosing CLKSEL_CON (i.e. div_shift and sel_shift) are variable. 329 */ 330 331 struct spi_clkreg { 332 uint8_t reg; /* CLKSEL_CON[reg] register in CRU */ 333 uint8_t div_shift; 334 uint8_t sel_shift; 335 }; 336 337 /* 338 * The entries are numbered relative to their offset from SCLK_SPI0. 339 */ 340 static const struct spi_clkreg spi_clkregs[] = { 341 [0] = { .reg = 45, .div_shift = 0, .sel_shift = 7, }, 342 [1] = { .reg = 45, .div_shift = 8, .sel_shift = 15, }, 343 [2] = { .reg = 46, .div_shift = 8, .sel_shift = 15, }, 344 }; 345 346 static inline u32 extract_bits(u32 val, unsigned width, unsigned shift) 347 { 348 return (val >> shift) & ((1 << width) - 1); 349 } 350 351 static ulong rk3368_spi_get_clk(struct rk3368_cru *cru, ulong clk_id) 352 { 353 const struct spi_clkreg *spiclk = NULL; 354 u32 div, val; 355 356 switch (clk_id) { 357 case SCLK_SPI0 ... SCLK_SPI2: 358 spiclk = &spi_clkregs[clk_id - SCLK_SPI0]; 359 break; 360 361 default: 362 error("%s: SPI clk-id %ld not supported\n", __func__, clk_id); 363 return -EINVAL; 364 } 365 366 val = readl(&cru->clksel_con[spiclk->reg]); 367 div = extract_bits(val, 7, spiclk->div_shift); 368 369 debug("%s: div 0x%x\n", __func__, div); 370 return DIV_TO_RATE(GPLL_HZ, div); 371 } 372 373 static ulong rk3368_spi_set_clk(struct rk3368_cru *cru, ulong clk_id, uint hz) 374 { 375 const struct spi_clkreg *spiclk = NULL; 376 int src_clk_div; 377 378 src_clk_div = DIV_ROUND_UP(GPLL_HZ, hz); 379 assert(src_clk_div < 127); 380 381 switch (clk_id) { 382 case SCLK_SPI0 ... SCLK_SPI2: 383 spiclk = &spi_clkregs[clk_id - SCLK_SPI0]; 384 break; 385 386 default: 387 error("%s: SPI clk-id %ld not supported\n", __func__, clk_id); 388 return -EINVAL; 389 } 390 391 rk_clrsetreg(&cru->clksel_con[spiclk->reg], 392 ((0x7f << spiclk->div_shift) | 393 (0x1 << spiclk->sel_shift)), 394 ((src_clk_div << spiclk->div_shift) | 395 (1 << spiclk->sel_shift))); 396 397 return rk3368_spi_get_clk(cru, clk_id); 398 } 399 400 static ulong rk3368_clk_get_rate(struct clk *clk) 401 { 402 struct rk3368_clk_priv *priv = dev_get_priv(clk->dev); 403 ulong rate = 0; 404 405 debug("%s: id %ld\n", __func__, clk->id); 406 switch (clk->id) { 407 case PLL_CPLL: 408 rate = rkclk_pll_get_rate(priv->cru, CPLL); 409 break; 410 case PLL_GPLL: 411 rate = rkclk_pll_get_rate(priv->cru, GPLL); 412 break; 413 case SCLK_SPI0 ... SCLK_SPI2: 414 rate = rk3368_spi_get_clk(priv->cru, clk->id); 415 break; 416 #if !IS_ENABLED(CONFIG_SPL_BUILD) || CONFIG_IS_ENABLED(MMC_SUPPORT) 417 case HCLK_SDMMC: 418 case HCLK_EMMC: 419 rate = rk3368_mmc_get_clk(priv->cru, clk->id); 420 break; 421 #endif 422 default: 423 return -ENOENT; 424 } 425 426 return rate; 427 } 428 429 static ulong rk3368_clk_set_rate(struct clk *clk, ulong rate) 430 { 431 __maybe_unused struct rk3368_clk_priv *priv = dev_get_priv(clk->dev); 432 ulong ret = 0; 433 434 debug("%s id:%ld rate:%ld\n", __func__, clk->id, rate); 435 switch (clk->id) { 436 case SCLK_SPI0 ... SCLK_SPI2: 437 ret = rk3368_spi_set_clk(priv->cru, clk->id, rate); 438 break; 439 #if IS_ENABLED(CONFIG_TPL_BUILD) 440 case CLK_DDR: 441 ret = rk3368_ddr_set_clk(priv->cru, rate); 442 break; 443 #endif 444 #if !IS_ENABLED(CONFIG_SPL_BUILD) || CONFIG_IS_ENABLED(MMC_SUPPORT) 445 case HCLK_SDMMC: 446 case HCLK_EMMC: 447 ret = rk3368_mmc_set_clk(clk, rate); 448 break; 449 #endif 450 #if CONFIG_IS_ENABLED(GMAC_ROCKCHIP) 451 case SCLK_MAC: 452 /* select the external clock */ 453 ret = rk3368_gmac_set_clk(priv->cru, clk->id, rate); 454 break; 455 #endif 456 default: 457 return -ENOENT; 458 } 459 460 return ret; 461 } 462 463 static struct clk_ops rk3368_clk_ops = { 464 .get_rate = rk3368_clk_get_rate, 465 .set_rate = rk3368_clk_set_rate, 466 }; 467 468 static int rk3368_clk_probe(struct udevice *dev) 469 { 470 struct rk3368_clk_priv __maybe_unused *priv = dev_get_priv(dev); 471 #if CONFIG_IS_ENABLED(OF_PLATDATA) 472 struct rk3368_clk_plat *plat = dev_get_platdata(dev); 473 474 priv->cru = map_sysmem(plat->dtd.reg[0], plat->dtd.reg[1]); 475 #endif 476 #if IS_ENABLED(CONFIG_SPL_BUILD) || IS_ENABLED(CONFIG_TPL_BUILD) 477 rkclk_init(priv->cru); 478 #endif 479 480 return 0; 481 } 482 483 static int rk3368_clk_ofdata_to_platdata(struct udevice *dev) 484 { 485 #if !CONFIG_IS_ENABLED(OF_PLATDATA) 486 struct rk3368_clk_priv *priv = dev_get_priv(dev); 487 488 priv->cru = dev_read_addr_ptr(dev); 489 #endif 490 491 return 0; 492 } 493 494 static int rk3368_clk_bind(struct udevice *dev) 495 { 496 int ret; 497 498 /* The reset driver does not have a device node, so bind it here */ 499 ret = device_bind_driver(gd->dm_root, "rk3368_sysreset", "reset", &dev); 500 if (ret) 501 error("bind RK3368 reset driver failed: ret=%d\n", ret); 502 503 return ret; 504 } 505 506 static const struct udevice_id rk3368_clk_ids[] = { 507 { .compatible = "rockchip,rk3368-cru" }, 508 { } 509 }; 510 511 U_BOOT_DRIVER(rockchip_rk3368_cru) = { 512 .name = "rockchip_rk3368_cru", 513 .id = UCLASS_CLK, 514 .of_match = rk3368_clk_ids, 515 .priv_auto_alloc_size = sizeof(struct rk3368_clk_priv), 516 #if CONFIG_IS_ENABLED(OF_PLATDATA) 517 .platdata_auto_alloc_size = sizeof(struct rk3368_clk_plat), 518 #endif 519 .ofdata_to_platdata = rk3368_clk_ofdata_to_platdata, 520 .ops = &rk3368_clk_ops, 521 .bind = rk3368_clk_bind, 522 .probe = rk3368_clk_probe, 523 }; 524