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 <bitfield.h> 16 #include <asm/arch/clock.h> 17 #include <asm/arch/cru_rk3368.h> 18 #include <asm/arch/hardware.h> 19 #include <asm/io.h> 20 #include <dm/lists.h> 21 #include <dt-bindings/clock/rk3368-cru.h> 22 23 DECLARE_GLOBAL_DATA_PTR; 24 25 #if CONFIG_IS_ENABLED(OF_PLATDATA) 26 struct rk3368_clk_plat { 27 struct dtd_rockchip_rk3368_cru dtd; 28 }; 29 #endif 30 31 struct pll_div { 32 ulong rate; 33 u32 nr; 34 u32 nf; 35 u32 no; 36 u32 nb; 37 }; 38 39 #define RK3368_PLL_RATE(_rate, _nr, _nf, _no, _nb) \ 40 { \ 41 .rate = _rate##U, \ 42 .nr = _nr, \ 43 .nf = _nf, \ 44 .no = _no, \ 45 .nb = _nb, \ 46 } 47 48 static struct pll_div rk3368_pll_rates[] = { 49 /* _mhz, _nr, _nf, _no, _nb */ 50 RK3368_PLL_RATE(594000000, 1, 99, 4, 16), 51 RK3368_PLL_RATE(424200000, 5, 707, 8, 0), 52 RK3368_PLL_RATE(410000000, 3, 205, 4, 16), 53 }; 54 55 #define OSC_HZ (24 * 1000 * 1000) 56 #define APLL_L_HZ (800 * 1000 * 1000) 57 #define APLL_B_HZ (816 * 1000 * 1000) 58 #define GPLL_HZ (576 * 1000 * 1000) 59 #define CPLL_HZ (400 * 1000 * 1000) 60 #define NPLL_HZ (594 * 1000 * 1000) 61 62 #define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1)) 63 64 #if !defined(CONFIG_SPL_BUILD) 65 #define RK3368_CLK_DUMP(_id, _name, _iscru) \ 66 { \ 67 .id = _id, \ 68 .name = _name, \ 69 .is_cru = _iscru, \ 70 } 71 72 static const struct rk3368_clk_info clks_dump[] = { 73 RK3368_CLK_DUMP(PLL_APLLB, "apllb", true), 74 RK3368_CLK_DUMP(PLL_APLLL, "aplll", true), 75 RK3368_CLK_DUMP(PLL_DPLL, "dpll", true), 76 RK3368_CLK_DUMP(PLL_CPLL, "cpll", true), 77 RK3368_CLK_DUMP(PLL_GPLL, "gpll", true), 78 RK3368_CLK_DUMP(PLL_NPLL, "npll", true), 79 RK3368_CLK_DUMP(ARMCLKB, "armclkb", true), 80 RK3368_CLK_DUMP(ARMCLKL, "armclkl", true), 81 RK3368_CLK_DUMP(ACLK_BUS, "aclk_bus", true), 82 RK3368_CLK_DUMP(HCLK_BUS, "hclk_bus", true), 83 RK3368_CLK_DUMP(PCLK_BUS, "pclk_Bus", true), 84 RK3368_CLK_DUMP(ACLK_PERI, "aclk_peri", true), 85 RK3368_CLK_DUMP(HCLK_PERI, "hclk_peri", true), 86 RK3368_CLK_DUMP(PCLK_PERI, "pclk_peri", true), 87 }; 88 #endif 89 90 #define RK3368_CPUCLK_RATE(_rate, _aclk_div, _pclk_div) \ 91 { \ 92 .rate = _rate##U, \ 93 .aclk_div = _aclk_div, \ 94 .pclk_div = _pclk_div, \ 95 } 96 97 static struct rockchip_cpu_rate_table rk3368_cpu_rates[] = { 98 #if !defined(CONFIG_SPL_BUILD) 99 RK3368_CPUCLK_RATE(1200000000, 1, 5), 100 RK3368_CPUCLK_RATE(1008000000, 1, 5), 101 #endif 102 RK3368_CPUCLK_RATE(816000000, 1, 3), 103 RK3368_CPUCLK_RATE(600000000, 1, 3), 104 }; 105 106 #define PLL_DIVISORS(hz, _nr, _no) { \ 107 .nr = _nr, .nf = (u32)((u64)hz * _nr * _no / OSC_HZ), .no = _no}; \ 108 _Static_assert(((u64)hz * _nr * _no / OSC_HZ) * OSC_HZ /\ 109 (_nr * _no) == hz, #hz "Hz cannot be hit with PLL " \ 110 "divisors on line " __stringify(__LINE__)); 111 112 #if IS_ENABLED(CONFIG_SPL_BUILD) || IS_ENABLED(CONFIG_TPL_BUILD) 113 static const struct pll_div apll_l_init_cfg = PLL_DIVISORS(APLL_L_HZ, 12, 2); 114 static const struct pll_div apll_b_init_cfg = PLL_DIVISORS(APLL_B_HZ, 1, 2); 115 #if !defined(CONFIG_TPL_BUILD) 116 static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 1, 2); 117 static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 6); 118 #endif 119 #endif 120 121 static ulong rk3368_clk_get_rate(struct clk *clk); 122 123 #define VCO_MAX_KHZ 2200000 124 #define VCO_MIN_KHZ 440000 125 #define FREF_MAX_KHZ 2200000 126 #define FREF_MIN_KHZ 269 127 #define PLL_LIMIT_FREQ 400000000 128 129 struct pll_div *rkclk_get_pll_config(ulong freq_hz) 130 { 131 unsigned int rate_count = ARRAY_SIZE(rk3368_pll_rates); 132 int i; 133 134 for (i = 0; i < rate_count; i++) { 135 if (freq_hz == rk3368_pll_rates[i].rate) 136 return &rk3368_pll_rates[i]; 137 } 138 return NULL; 139 } 140 141 static int pll_para_config(ulong freq_hz, struct pll_div *div, uint *ext_div) 142 { 143 struct pll_div *best_div = NULL; 144 uint ref_khz = OSC_HZ / 1000, nr, nf = 0; 145 uint fref_khz; 146 uint diff_khz, best_diff_khz; 147 const uint max_nr = 1 << 6, max_nf = 1 << 12, max_no = 1 << 4; 148 uint vco_khz; 149 uint no = 1; 150 uint freq_khz = freq_hz / 1000; 151 152 if (!freq_hz) { 153 printf("%s: the frequency can not be 0 Hz\n", __func__); 154 return -EINVAL; 155 } 156 157 no = DIV_ROUND_UP(VCO_MIN_KHZ, freq_khz); 158 if (ext_div) { 159 *ext_div = DIV_ROUND_UP(PLL_LIMIT_FREQ, freq_hz); 160 no = DIV_ROUND_UP(no, *ext_div); 161 } 162 163 best_div = rkclk_get_pll_config(freq_hz * (*ext_div)); 164 if (best_div) { 165 div->nr = best_div->nr; 166 div->nf = best_div->nf; 167 div->no = best_div->no; 168 div->nb = best_div->nb; 169 return 0; 170 } 171 172 /* only even divisors (and 1) are supported */ 173 if (no > 1) 174 no = DIV_ROUND_UP(no, 2) * 2; 175 176 vco_khz = freq_khz * no; 177 if (ext_div) 178 vco_khz *= *ext_div; 179 180 if (vco_khz < VCO_MIN_KHZ || vco_khz > VCO_MAX_KHZ || no > max_no) { 181 printf("%s: Cannot find out VCO for Frequency (%luHz).\n", 182 __func__, freq_hz); 183 return -1; 184 } 185 186 div->no = no; 187 188 best_diff_khz = vco_khz; 189 for (nr = 1; nr < max_nr && best_diff_khz; nr++) { 190 fref_khz = ref_khz / nr; 191 if (fref_khz < FREF_MIN_KHZ) 192 break; 193 if (fref_khz > FREF_MAX_KHZ) 194 continue; 195 196 nf = vco_khz / fref_khz; 197 if (nf >= max_nf) 198 continue; 199 diff_khz = vco_khz - nf * fref_khz; 200 if (nf + 1 < max_nf && diff_khz > fref_khz / 2) { 201 nf++; 202 diff_khz = fref_khz - diff_khz; 203 } 204 205 if (diff_khz >= best_diff_khz) 206 continue; 207 208 best_diff_khz = diff_khz; 209 div->nr = nr; 210 div->nf = nf; 211 } 212 213 if (best_diff_khz > 4 * 1000) { 214 printf("%s:Fail to match output freq %lu,best_is %u Hz\n", 215 __func__, freq_hz, best_diff_khz * 1000); 216 return -EINVAL; 217 } 218 219 return 0; 220 } 221 222 /* Get pll rate by id */ 223 static uint32_t rkclk_pll_get_rate(struct rk3368_cru *cru, 224 enum rk3368_pll_id pll_id) 225 { 226 uint32_t nr, no, nf; 227 uint32_t con; 228 struct rk3368_pll *pll = &cru->pll[pll_id]; 229 230 con = readl(&pll->con3); 231 232 switch ((con & PLL_MODE_MASK) >> PLL_MODE_SHIFT) { 233 case PLL_MODE_SLOW: 234 return OSC_HZ; 235 case PLL_MODE_NORMAL: 236 con = readl(&pll->con0); 237 no = ((con & PLL_OD_MASK) >> PLL_OD_SHIFT) + 1; 238 nr = ((con & PLL_NR_MASK) >> PLL_NR_SHIFT) + 1; 239 con = readl(&pll->con1); 240 nf = ((con & PLL_NF_MASK) >> PLL_NF_SHIFT) + 1; 241 242 return (24 * nf / (nr * no)) * 1000000; 243 case PLL_MODE_DEEP_SLOW: 244 default: 245 return 32768; 246 } 247 } 248 249 static int rkclk_set_pll(struct rk3368_cru *cru, enum rk3368_pll_id pll_id, 250 const struct pll_div *div) 251 { 252 struct rk3368_pll *pll = &cru->pll[pll_id]; 253 /* All PLLs have same VCO and output frequency range restrictions*/ 254 uint vco_hz = OSC_HZ / 1000 * div->nf / div->nr * 1000; 255 uint output_hz = vco_hz / div->no; 256 257 debug("PLL at %p: nf=%d, nr=%d, no=%d, vco=%u Hz, output=%u Hz\n", 258 pll, div->nf, div->nr, div->no, vco_hz, output_hz); 259 260 /* enter slow mode and reset pll */ 261 rk_clrsetreg(&pll->con3, PLL_MODE_MASK | PLL_RESET_MASK, 262 PLL_RESET << PLL_RESET_SHIFT); 263 264 rk_clrsetreg(&pll->con0, PLL_NR_MASK | PLL_OD_MASK, 265 ((div->nr - 1) << PLL_NR_SHIFT) | 266 ((div->no - 1) << PLL_OD_SHIFT)); 267 writel((div->nf - 1) << PLL_NF_SHIFT, &pll->con1); 268 /* 269 * BWADJ should be set to NF / 2 to ensure the nominal bandwidth. 270 * Compare the RK3368 TRM, section "3.6.4 PLL Bandwidth Adjustment". 271 */ 272 if (div->nb) 273 clrsetbits_le32(&pll->con2, PLL_BWADJ_MASK, div->nb - 1); 274 else 275 clrsetbits_le32(&pll->con2, PLL_BWADJ_MASK, (div->nf >> 1) - 1); 276 277 udelay(10); 278 279 /* return from reset */ 280 rk_clrreg(&pll->con3, PLL_RESET_MASK); 281 282 /* waiting for pll lock */ 283 while (!(readl(&pll->con1) & PLL_LOCK_STA)) 284 udelay(1); 285 286 rk_clrsetreg(&pll->con3, PLL_MODE_MASK, 287 PLL_MODE_NORMAL << PLL_MODE_SHIFT); 288 289 return 0; 290 } 291 292 #if !IS_ENABLED(CONFIG_SPL_BUILD) || CONFIG_IS_ENABLED(MMC_SUPPORT) 293 static ulong rk3368_mmc_get_clk(struct rk3368_cru *cru, uint clk_id) 294 { 295 u32 div, con, con_id, rate; 296 u32 pll_rate; 297 298 switch (clk_id) { 299 case HCLK_SDMMC: 300 con_id = 50; 301 break; 302 case HCLK_EMMC: 303 con_id = 51; 304 break; 305 case SCLK_SDIO0: 306 con_id = 48; 307 break; 308 default: 309 return -EINVAL; 310 } 311 312 con = readl(&cru->clksel_con[con_id]); 313 switch (con & MMC_PLL_SEL_MASK) { 314 case MMC_PLL_SEL_GPLL: 315 pll_rate = rkclk_pll_get_rate(cru, GPLL); 316 break; 317 case MMC_PLL_SEL_24M: 318 pll_rate = OSC_HZ; 319 break; 320 case MMC_PLL_SEL_CPLL: 321 pll_rate = rkclk_pll_get_rate(cru, CPLL); 322 break; 323 case MMC_PLL_SEL_USBPHY_480M: 324 default: 325 return -EINVAL; 326 } 327 div = (con & MMC_CLK_DIV_MASK) >> MMC_CLK_DIV_SHIFT; 328 rate = DIV_TO_RATE(pll_rate, div); 329 330 debug("%s: raw rate %d (post-divide by 2)\n", __func__, rate); 331 return rate >> 1; 332 } 333 334 static ulong rk3368_mmc_find_best_rate_and_parent(struct clk *clk, 335 ulong rate, 336 u32 *best_mux, 337 u32 *best_div) 338 { 339 int i; 340 ulong best_rate = 0; 341 const ulong MHz = 1000000; 342 const struct { 343 u32 mux; 344 ulong rate; 345 } parents[] = { 346 { .mux = MMC_PLL_SEL_CPLL, .rate = CPLL_HZ }, 347 { .mux = MMC_PLL_SEL_GPLL, .rate = GPLL_HZ }, 348 { .mux = MMC_PLL_SEL_24M, .rate = 24 * MHz } 349 }; 350 351 debug("%s: target rate %ld\n", __func__, rate); 352 for (i = 0; i < ARRAY_SIZE(parents); ++i) { 353 /* 354 * Find the largest rate no larger than the target-rate for 355 * the current parent. 356 */ 357 ulong parent_rate = parents[i].rate; 358 u32 div = DIV_ROUND_UP(parent_rate, rate); 359 u32 adj_div = div; 360 ulong new_rate = parent_rate / adj_div; 361 362 debug("%s: rate %ld, parent-mux %d, parent-rate %ld, div %d\n", 363 __func__, rate, parents[i].mux, parents[i].rate, div); 364 365 /* Skip, if not representable */ 366 if ((div - 1) > MMC_CLK_DIV_MASK) 367 continue; 368 369 /* Skip, if we already have a better (or equal) solution */ 370 if (new_rate <= best_rate) 371 continue; 372 373 /* This is our new best rate. */ 374 best_rate = new_rate; 375 *best_mux = parents[i].mux; 376 *best_div = div - 1; 377 } 378 379 debug("%s: best_mux = %x, best_div = %d, best_rate = %ld\n", 380 __func__, *best_mux, *best_div, best_rate); 381 382 return best_rate; 383 } 384 385 static ulong rk3368_mmc_set_clk(struct clk *clk, ulong rate) 386 { 387 struct rk3368_clk_priv *priv = dev_get_priv(clk->dev); 388 struct rk3368_cru *cru = priv->cru; 389 ulong clk_id = clk->id; 390 u32 con_id, mux = 0, div = 0; 391 392 /* Find the best parent and rate */ 393 rk3368_mmc_find_best_rate_and_parent(clk, rate << 1, &mux, &div); 394 395 switch (clk_id) { 396 case HCLK_SDMMC: 397 con_id = 50; 398 break; 399 case HCLK_EMMC: 400 con_id = 51; 401 break; 402 case SCLK_SDIO0: 403 con_id = 48; 404 break; 405 default: 406 return -EINVAL; 407 } 408 409 rk_clrsetreg(&cru->clksel_con[con_id], 410 MMC_PLL_SEL_MASK | MMC_CLK_DIV_MASK, 411 mux | div); 412 413 return rk3368_mmc_get_clk(cru, clk_id); 414 } 415 #endif 416 417 #if IS_ENABLED(CONFIG_TPL_BUILD) 418 static ulong rk3368_ddr_set_clk(struct rk3368_cru *cru, ulong set_rate) 419 { 420 const struct pll_div *dpll_cfg = NULL; 421 const ulong MHz = 1000000; 422 423 /* Fout = ((Fin /NR) * NF )/ NO */ 424 static const struct pll_div dpll_1200 = PLL_DIVISORS(1200 * MHz, 1, 1); 425 static const struct pll_div dpll_1332 = PLL_DIVISORS(1332 * MHz, 2, 1); 426 static const struct pll_div dpll_1600 = PLL_DIVISORS(1600 * MHz, 3, 2); 427 428 switch (set_rate) { 429 case 1200*MHz: 430 dpll_cfg = &dpll_1200; 431 break; 432 case 1332*MHz: 433 dpll_cfg = &dpll_1332; 434 break; 435 case 1600*MHz: 436 dpll_cfg = &dpll_1600; 437 break; 438 default: 439 pr_err("Unsupported SDRAM frequency!,%ld\n", set_rate); 440 } 441 rkclk_set_pll(cru, DPLL, dpll_cfg); 442 443 return set_rate; 444 } 445 #endif 446 447 #if CONFIG_IS_ENABLED(GMAC_ROCKCHIP) 448 static ulong rk3368_gmac_set_clk(struct rk3368_cru *cru, ulong set_rate) 449 { 450 ulong ret; 451 452 /* 453 * The gmac clock can be derived either from an external clock 454 * or can be generated from internally by a divider from SCLK_MAC. 455 */ 456 if (readl(&cru->clksel_con[43]) & GMAC_MUX_SEL_EXTCLK) { 457 /* An external clock will always generate the right rate... */ 458 ret = set_rate; 459 } else { 460 u32 con = readl(&cru->clksel_con[43]); 461 ulong pll_rate; 462 u8 div; 463 464 if (((con >> GMAC_PLL_SHIFT) & GMAC_PLL_MASK) == 465 GMAC_PLL_SELECT_GENERAL) 466 pll_rate = GPLL_HZ; 467 else if (((con >> GMAC_PLL_SHIFT) & GMAC_PLL_MASK) == 468 GMAC_PLL_SELECT_CODEC) 469 pll_rate = CPLL_HZ; 470 else 471 /* CPLL is not set */ 472 return -EPERM; 473 474 div = DIV_ROUND_UP(pll_rate, set_rate) - 1; 475 if (div <= 0x1f) 476 rk_clrsetreg(&cru->clksel_con[43], GMAC_DIV_CON_MASK, 477 div << GMAC_DIV_CON_SHIFT); 478 else 479 debug("Unsupported div for gmac:%d\n", div); 480 481 return DIV_TO_RATE(pll_rate, div); 482 } 483 484 return ret; 485 } 486 #endif 487 488 /* 489 * RK3368 SPI clocks have a common divider-width (7 bits) and a single bit 490 * to select either CPLL or GPLL as the clock-parent. The location within 491 * the enclosing CLKSEL_CON (i.e. div_shift and sel_shift) are variable. 492 */ 493 494 struct spi_clkreg { 495 uint8_t reg; /* CLKSEL_CON[reg] register in CRU */ 496 uint8_t div_shift; 497 uint8_t sel_shift; 498 }; 499 500 /* 501 * The entries are numbered relative to their offset from SCLK_SPI0. 502 */ 503 static const struct spi_clkreg spi_clkregs[] = { 504 [0] = { .reg = 45, .div_shift = 0, .sel_shift = 7, }, 505 [1] = { .reg = 45, .div_shift = 8, .sel_shift = 15, }, 506 [2] = { .reg = 46, .div_shift = 8, .sel_shift = 15, }, 507 }; 508 509 static inline u32 extract_bits(u32 val, unsigned width, unsigned shift) 510 { 511 return (val >> shift) & ((1 << width) - 1); 512 } 513 514 static ulong rk3368_spi_get_clk(struct rk3368_cru *cru, ulong clk_id) 515 { 516 const struct spi_clkreg *spiclk = NULL; 517 u32 div, val; 518 519 switch (clk_id) { 520 case SCLK_SPI0 ... SCLK_SPI2: 521 spiclk = &spi_clkregs[clk_id - SCLK_SPI0]; 522 break; 523 524 default: 525 pr_err("%s: SPI clk-id %ld not supported\n", __func__, clk_id); 526 return -EINVAL; 527 } 528 529 val = readl(&cru->clksel_con[spiclk->reg]); 530 div = extract_bits(val, 7, spiclk->div_shift); 531 532 debug("%s: div 0x%x\n", __func__, div); 533 return DIV_TO_RATE(GPLL_HZ, div); 534 } 535 536 static ulong rk3368_spi_set_clk(struct rk3368_cru *cru, ulong clk_id, uint hz) 537 { 538 const struct spi_clkreg *spiclk = NULL; 539 int src_clk_div; 540 541 src_clk_div = DIV_ROUND_UP(GPLL_HZ, hz); 542 assert(src_clk_div < 127); 543 544 switch (clk_id) { 545 case SCLK_SPI0 ... SCLK_SPI2: 546 spiclk = &spi_clkregs[clk_id - SCLK_SPI0]; 547 break; 548 549 default: 550 pr_err("%s: SPI clk-id %ld not supported\n", __func__, clk_id); 551 return -EINVAL; 552 } 553 554 rk_clrsetreg(&cru->clksel_con[spiclk->reg], 555 ((0x7f << spiclk->div_shift) | 556 (0x1 << spiclk->sel_shift)), 557 ((src_clk_div << spiclk->div_shift) | 558 (1 << spiclk->sel_shift))); 559 560 return rk3368_spi_get_clk(cru, clk_id); 561 } 562 563 static ulong rk3368_saradc_get_clk(struct rk3368_cru *cru) 564 { 565 u32 div, val; 566 567 val = readl(&cru->clksel_con[25]); 568 div = bitfield_extract(val, CLK_SARADC_DIV_CON_SHIFT, 569 CLK_SARADC_DIV_CON_WIDTH); 570 571 return DIV_TO_RATE(OSC_HZ, div); 572 } 573 574 static ulong rk3368_saradc_set_clk(struct rk3368_cru *cru, uint hz) 575 { 576 int src_clk_div; 577 578 src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1; 579 assert(src_clk_div < 128); 580 581 rk_clrsetreg(&cru->clksel_con[25], 582 CLK_SARADC_DIV_CON_MASK, 583 src_clk_div << CLK_SARADC_DIV_CON_SHIFT); 584 585 return rk3368_saradc_get_clk(cru); 586 } 587 588 static ulong rk3368_bus_get_clk(struct rk3368_cru *cru, ulong clk_id) 589 { 590 u32 div, con, parent; 591 592 switch (clk_id) { 593 case ACLK_BUS: 594 con = readl(&cru->clksel_con[8]); 595 div = (con & ACLK_BUS_DIV_CON_MASK) >> ACLK_BUS_DIV_CON_SHIFT; 596 parent = rkclk_pll_get_rate(cru, GPLL); 597 break; 598 case HCLK_BUS: 599 con = readl(&cru->clksel_con[8]); 600 div = (con & HCLK_BUS_DIV_CON_MASK) >> HCLK_BUS_DIV_CON_SHIFT; 601 parent = rk3368_bus_get_clk(cru, ACLK_BUS); 602 break; 603 case PCLK_BUS: 604 case PCLK_PWM0: 605 case PCLK_PWM1: 606 case PCLK_I2C0: 607 case PCLK_I2C1: 608 con = readl(&cru->clksel_con[8]); 609 div = (con & PCLK_BUS_DIV_CON_MASK) >> PCLK_BUS_DIV_CON_SHIFT; 610 parent = rk3368_bus_get_clk(cru, ACLK_BUS); 611 break; 612 default: 613 return -ENOENT; 614 } 615 616 return DIV_TO_RATE(parent, div); 617 } 618 619 static ulong rk3368_bus_set_clk(struct rk3368_cru *cru, 620 ulong clk_id, ulong hz) 621 { 622 int src_clk_div; 623 624 /* 625 * select gpll as pd_bus bus clock source and 626 * set up dependent divisors for PCLK/HCLK and ACLK clocks. 627 */ 628 switch (clk_id) { 629 case ACLK_BUS: 630 src_clk_div = DIV_ROUND_UP(rkclk_pll_get_rate(cru, GPLL), hz); 631 assert(src_clk_div - 1 < 31); 632 rk_clrsetreg(&cru->clksel_con[8], 633 CLK_BUS_PLL_SEL_MASK | ACLK_BUS_DIV_CON_MASK, 634 CLK_BUS_PLL_SEL_GPLL << CLK_BUS_PLL_SEL_SHIFT | 635 (src_clk_div - 1) << ACLK_BUS_DIV_CON_SHIFT); 636 break; 637 case HCLK_BUS: 638 src_clk_div = DIV_ROUND_UP(rk3368_bus_get_clk(cru, 639 ACLK_BUS), 640 hz); 641 assert(src_clk_div - 1 < 3); 642 rk_clrsetreg(&cru->clksel_con[8], 643 HCLK_BUS_DIV_CON_MASK, 644 (src_clk_div - 1) << HCLK_BUS_DIV_CON_SHIFT); 645 break; 646 case PCLK_BUS: 647 src_clk_div = DIV_ROUND_UP(rk3368_bus_get_clk(cru, 648 ACLK_BUS), 649 hz); 650 assert(src_clk_div - 1 < 3); 651 rk_clrsetreg(&cru->clksel_con[8], 652 PCLK_BUS_DIV_CON_MASK, 653 (src_clk_div - 1) << PCLK_BUS_DIV_CON_SHIFT); 654 break; 655 default: 656 printf("do not support this bus freq\n"); 657 return -EINVAL; 658 } 659 return rk3368_bus_get_clk(cru, clk_id); 660 } 661 662 static ulong rk3368_peri_get_clk(struct rk3368_cru *cru, ulong clk_id) 663 { 664 u32 div, con, parent; 665 666 switch (clk_id) { 667 case ACLK_PERI: 668 con = readl(&cru->clksel_con[9]); 669 div = (con & ACLK_PERI_DIV_CON_MASK) >> ACLK_PERI_DIV_CON_SHIFT; 670 parent = rkclk_pll_get_rate(cru, GPLL); 671 break; 672 case HCLK_PERI: 673 con = readl(&cru->clksel_con[9]); 674 div = (con & HCLK_PERI_DIV_CON_MASK) >> HCLK_PERI_DIV_CON_SHIFT; 675 parent = rk3368_peri_get_clk(cru, ACLK_PERI); 676 break; 677 case PCLK_PERI: 678 case PCLK_I2C2: 679 case PCLK_I2C3: 680 case PCLK_I2C4: 681 case PCLK_I2C5: 682 con = readl(&cru->clksel_con[9]); 683 div = (con & PCLK_PERI_DIV_CON_MASK) >> PCLK_PERI_DIV_CON_SHIFT; 684 parent = rk3368_peri_get_clk(cru, ACLK_PERI); 685 break; 686 default: 687 return -ENOENT; 688 } 689 690 return DIV_TO_RATE(parent, div); 691 } 692 693 static ulong rk3368_peri_set_clk(struct rk3368_cru *cru, 694 ulong clk_id, ulong hz) 695 { 696 int src_clk_div; 697 698 /* 699 * select gpll as pd_bus bus clock source and 700 * set up dependent divisors for PCLK/HCLK and ACLK clocks. 701 */ 702 switch (clk_id) { 703 case ACLK_PERI: 704 src_clk_div = DIV_ROUND_UP(rkclk_pll_get_rate(cru, GPLL), hz); 705 assert(src_clk_div - 1 < 31); 706 rk_clrsetreg(&cru->clksel_con[9], 707 CLK_PERI_PLL_SEL_MASK | ACLK_PERI_DIV_CON_MASK, 708 CLK_PERI_PLL_SEL_GPLL << CLK_PERI_PLL_SEL_SHIFT | 709 (src_clk_div - 1) << ACLK_PERI_DIV_CON_SHIFT); 710 break; 711 case HCLK_PERI: 712 src_clk_div = DIV_ROUND_UP(rk3368_peri_get_clk(cru, 713 ACLK_PERI), 714 hz); 715 assert(src_clk_div - 1 < 3); 716 rk_clrsetreg(&cru->clksel_con[9], 717 HCLK_PERI_DIV_CON_MASK, 718 (src_clk_div - 1) << HCLK_PERI_DIV_CON_SHIFT); 719 break; 720 case PCLK_PERI: 721 src_clk_div = DIV_ROUND_UP(rk3368_peri_get_clk(cru, 722 ACLK_PERI), 723 hz); 724 assert(src_clk_div - 1 < 3); 725 rk_clrsetreg(&cru->clksel_con[9], 726 PCLK_PERI_DIV_CON_MASK, 727 (src_clk_div - 1) << PCLK_PERI_DIV_CON_SHIFT); 728 break; 729 default: 730 printf("do not support this bus freq\n"); 731 return -EINVAL; 732 } 733 734 return rk3368_peri_get_clk(cru, clk_id); 735 } 736 737 #if !defined(CONFIG_SPL_BUILD) 738 static ulong rk3368_vop_get_clk(struct rk3368_cru *cru, int clk_id) 739 { 740 u32 div, con, parent, sel; 741 742 switch (clk_id) { 743 case DCLK_VOP: 744 con = readl(&cru->clksel_con[20]); 745 div = con & DCLK_VOP_DIV_MASK; 746 parent = rkclk_pll_get_rate(cru, NPLL); 747 break; 748 case ACLK_VOP: 749 con = readl(&cru->clksel_con[19]); 750 div = con & ACLK_VOP_DIV_MASK; 751 sel = (con & (ACLK_VOP_PLL_SEL_MASK << 752 ACLK_VOP_PLL_SEL_SHIFT)) >> 753 ACLK_VOP_PLL_SEL_SHIFT; 754 if (sel == ACLK_VOP_PLL_SEL_CPLL) 755 parent = rkclk_pll_get_rate(cru, CPLL); 756 else if (ACLK_VOP_PLL_SEL_GPLL) 757 parent = rkclk_pll_get_rate(cru, GPLL); 758 else 759 parent = 480000000; 760 break; 761 default: 762 return -EINVAL; 763 } 764 765 return DIV_TO_RATE(parent, div); 766 } 767 768 static ulong rk3368_vop_set_clk(struct rk3368_cru *cru, int clk_id, uint hz) 769 { 770 struct pll_div npll_config = {0}; 771 u32 lcdc_div; 772 int ret; 773 774 switch (clk_id) { 775 case DCLK_VOP: 776 if (!(NPLL_HZ % hz)) { 777 rkclk_set_pll(cru, NPLL, rkclk_get_pll_config(NPLL_HZ)); 778 lcdc_div = NPLL_HZ / hz; 779 } else { 780 ret = pll_para_config(hz, &npll_config, &lcdc_div); 781 if (ret) 782 return ret; 783 784 rkclk_set_pll(cru, NPLL, &npll_config); 785 } 786 /* vop dclk source clk: npll,dclk_div: 1 */ 787 rk_clrsetreg(&cru->clksel_con[20], 788 (DCLK_VOP_PLL_SEL_MASK << DCLK_VOP_PLL_SEL_SHIFT) | 789 (DCLK_VOP_DIV_MASK << DCLK_VOP_DIV_SHIFT), 790 (DCLK_VOP_PLL_SEL_NPLL << DCLK_VOP_PLL_SEL_SHIFT) | 791 (lcdc_div - 1) << DCLK_VOP_DIV_SHIFT); 792 break; 793 case ACLK_VOP: 794 if ((rkclk_pll_get_rate(cru, CPLL) % hz) == 0) { 795 lcdc_div = rkclk_pll_get_rate(cru, CPLL) / hz; 796 rk_clrsetreg(&cru->clksel_con[19], 797 (ACLK_VOP_PLL_SEL_MASK << 798 ACLK_VOP_PLL_SEL_SHIFT) | 799 (ACLK_VOP_DIV_MASK << 800 ACLK_VOP_DIV_SHIFT), 801 (ACLK_VOP_PLL_SEL_CPLL << 802 ACLK_VOP_PLL_SEL_SHIFT) | 803 (lcdc_div - 1) << 804 ACLK_VOP_DIV_SHIFT); 805 } else { 806 lcdc_div = rkclk_pll_get_rate(cru, GPLL) / hz; 807 rk_clrsetreg(&cru->clksel_con[19], 808 (ACLK_VOP_PLL_SEL_MASK << 809 ACLK_VOP_PLL_SEL_SHIFT) | 810 (ACLK_VOP_DIV_MASK << 811 ACLK_VOP_DIV_SHIFT), 812 (ACLK_VOP_PLL_SEL_GPLL << 813 ACLK_VOP_PLL_SEL_SHIFT) | 814 (lcdc_div - 1) << 815 ACLK_VOP_DIV_SHIFT); 816 } 817 break; 818 default: 819 return -EINVAL; 820 } 821 822 return 0; 823 } 824 825 static ulong rk3368_alive_get_clk(struct rk3368_clk_priv *priv) 826 { 827 struct rk3368_cru *cru = priv->cru; 828 u32 div, con, parent; 829 830 con = readl(&cru->clksel_con[10]); 831 div = (con & PCLK_ALIVE_DIV_CON_MASK) >> 832 PCLK_ALIVE_DIV_CON_SHIFT; 833 parent = GPLL_HZ; 834 return DIV_TO_RATE(parent, div); 835 } 836 837 static ulong rk3368_crypto_get_rate(struct rk3368_clk_priv *priv) 838 { 839 struct rk3368_cru *cru = priv->cru; 840 u32 div, val; 841 842 val = readl(&cru->clksel_con[10]); 843 div = (val & CLK_CRYPTO_DIV_CON_MASK) >> CLK_CRYPTO_DIV_CON_SHIFT; 844 845 return DIV_TO_RATE(rk3368_bus_get_clk(priv->cru, ACLK_BUS), div); 846 } 847 848 static ulong rk3368_crypto_set_rate(struct rk3368_clk_priv *priv, 849 uint hz) 850 { 851 struct rk3368_cru *cru = priv->cru; 852 int src_clk_div; 853 uint p_rate; 854 855 p_rate = rk3368_bus_get_clk(priv->cru, ACLK_BUS); 856 src_clk_div = DIV_ROUND_UP(p_rate, hz) - 1; 857 assert(src_clk_div < 3); 858 859 rk_clrsetreg(&cru->clksel_con[10], 860 CLK_CRYPTO_DIV_CON_MASK, 861 src_clk_div << CLK_CRYPTO_DIV_CON_SHIFT); 862 863 return rk3368_crypto_get_rate(priv); 864 } 865 #endif 866 867 static ulong rk3368_armclk_set_clk(struct rk3368_clk_priv *priv, 868 int clk_id, ulong hz) 869 { 870 struct rk3368_cru *cru = priv->cru; 871 const struct rockchip_cpu_rate_table *rate; 872 struct pll_div pll_config = {0}; 873 ulong old_rate; 874 u32 pll_div, pll_id, con_id; 875 int ret; 876 877 rate = rockchip_get_cpu_settings(rk3368_cpu_rates, hz); 878 if (!rate) { 879 printf("%s unsupported rate\n", __func__); 880 return -EINVAL; 881 } 882 883 /* 884 * select apll as cpu/core clock pll source and 885 * set up dependent divisors for PERI and ACLK clocks. 886 * core hz : apll = 1:1 887 */ 888 889 ret = pll_para_config(hz, &pll_config, &pll_div); 890 if (ret) 891 return ret; 892 893 if (clk_id == ARMCLKB) { 894 old_rate = rkclk_pll_get_rate(priv->cru, APLLB); 895 pll_id = APLLB; 896 con_id = 0; 897 } else { 898 old_rate = rkclk_pll_get_rate(priv->cru, APLLL); 899 pll_id = APLLL; 900 con_id = 2; 901 } 902 903 if (old_rate > hz) { 904 ret = rkclk_set_pll(priv->cru, pll_id, &pll_config); 905 rk_clrsetreg(&cru->clksel_con[con_id], 906 CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK, 907 CORE_CLK_PLL_SEL_APLL << CORE_CLK_PLL_SEL_SHIFT | 908 0 << CORE_DIV_CON_SHIFT); 909 rk_clrsetreg(&cru->clksel_con[con_id + 1], 910 CORE_ACLK_DIV_MASK | CORE_DBG_DIV_MASK, 911 rate->aclk_div << CORE_ACLK_DIV_SHIFT | 912 rate->pclk_div << CORE_DBG_DIV_SHIFT); 913 } else if (old_rate < hz) { 914 rk_clrsetreg(&cru->clksel_con[con_id], 915 CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK, 916 CORE_CLK_PLL_SEL_APLL << CORE_CLK_PLL_SEL_SHIFT | 917 0 << CORE_DIV_CON_SHIFT); 918 rk_clrsetreg(&cru->clksel_con[con_id + 1], 919 CORE_ACLK_DIV_MASK | CORE_DBG_DIV_MASK, 920 rate->aclk_div << CORE_ACLK_DIV_SHIFT | 921 rate->pclk_div << CORE_DBG_DIV_SHIFT); 922 ret = rkclk_set_pll(priv->cru, pll_id, &pll_config); 923 } 924 925 return rkclk_pll_get_rate(priv->cru, pll_id); 926 } 927 928 static ulong rk3368_clk_get_rate(struct clk *clk) 929 { 930 struct rk3368_clk_priv *priv = dev_get_priv(clk->dev); 931 ulong rate = 0; 932 933 debug("%s: id %ld\n", __func__, clk->id); 934 switch (clk->id) { 935 case PLL_APLLB: 936 case PLL_APLLL: 937 case PLL_DPLL: 938 case PLL_CPLL: 939 case PLL_GPLL: 940 case PLL_NPLL: 941 rate = rkclk_pll_get_rate(priv->cru, clk->id - 1); 942 break; 943 case ARMCLKB: 944 rate = rkclk_pll_get_rate(priv->cru, APLLB); 945 break; 946 case ARMCLKL: 947 rate = rkclk_pll_get_rate(priv->cru, APLLL); 948 break; 949 case SCLK_SPI0 ... SCLK_SPI2: 950 rate = rk3368_spi_get_clk(priv->cru, clk->id); 951 break; 952 case ACLK_BUS: 953 case HCLK_BUS: 954 case PCLK_BUS: 955 case PCLK_PWM0: 956 case PCLK_PWM1: 957 case PCLK_I2C0: 958 case PCLK_I2C1: 959 rate = rk3368_bus_get_clk(priv->cru, clk->id); 960 break; 961 case ACLK_PERI: 962 case HCLK_PERI: 963 case PCLK_PERI: 964 case PCLK_I2C2: 965 case PCLK_I2C3: 966 case PCLK_I2C4: 967 case PCLK_I2C5: 968 rate = rk3368_peri_get_clk(priv->cru, clk->id); 969 break; 970 #if !IS_ENABLED(CONFIG_SPL_BUILD) || CONFIG_IS_ENABLED(MMC_SUPPORT) 971 case HCLK_SDMMC: 972 case HCLK_EMMC: 973 rate = rk3368_mmc_get_clk(priv->cru, clk->id); 974 break; 975 #endif 976 case SCLK_SARADC: 977 rate = rk3368_saradc_get_clk(priv->cru); 978 break; 979 #if !defined(CONFIG_SPL_BUILD) 980 case ACLK_VOP: 981 case DCLK_VOP: 982 rate = rk3368_vop_get_clk(priv->cru, clk->id); 983 break; 984 case PCLK_WDT: 985 rate = rk3368_alive_get_clk(priv); 986 break; 987 case SCLK_CRYPTO: 988 rate = rk3368_crypto_get_rate(priv); 989 break; 990 #endif 991 default: 992 return -ENOENT; 993 } 994 return rate; 995 } 996 997 static ulong rk3368_clk_set_rate(struct clk *clk, ulong rate) 998 { 999 __maybe_unused struct rk3368_clk_priv *priv = dev_get_priv(clk->dev); 1000 struct pll_div pll_config = {0}; 1001 u32 pll_div; 1002 ulong ret = 0; 1003 1004 switch (clk->id) { 1005 case PLL_APLLB: 1006 case PLL_APLLL: 1007 case PLL_CPLL: 1008 case PLL_GPLL: 1009 case PLL_NPLL: 1010 ret = pll_para_config(rate, &pll_config, &pll_div); 1011 if (ret) 1012 return ret; 1013 1014 ret = rkclk_set_pll(priv->cru, clk->id - 1, &pll_config); 1015 break; 1016 case ARMCLKB: 1017 if (priv->armbclk_hz) 1018 ret = rk3368_armclk_set_clk(priv, clk->id, rate); 1019 priv->armbclk_hz = rate; 1020 break; 1021 case ARMCLKL: 1022 if (priv->armlclk_hz) 1023 ret = rk3368_armclk_set_clk(priv, clk->id, rate); 1024 priv->armlclk_hz = rate; 1025 break; 1026 case SCLK_SPI0 ... SCLK_SPI2: 1027 ret = rk3368_spi_set_clk(priv->cru, clk->id, rate); 1028 break; 1029 #if IS_ENABLED(CONFIG_TPL_BUILD) 1030 case SCLK_DDRCLK: 1031 ret = rk3368_ddr_set_clk(priv->cru, rate); 1032 break; 1033 #endif 1034 case ACLK_BUS: 1035 case HCLK_BUS: 1036 case PCLK_BUS: 1037 rate = rk3368_bus_set_clk(priv->cru, clk->id, rate); 1038 break; 1039 case ACLK_PERI: 1040 case HCLK_PERI: 1041 case PCLK_PERI: 1042 rate = rk3368_peri_set_clk(priv->cru, clk->id, rate); 1043 break; 1044 #if !IS_ENABLED(CONFIG_SPL_BUILD) || CONFIG_IS_ENABLED(MMC_SUPPORT) 1045 case HCLK_SDMMC: 1046 case HCLK_EMMC: 1047 ret = rk3368_mmc_set_clk(clk, rate); 1048 break; 1049 #endif 1050 #if CONFIG_IS_ENABLED(GMAC_ROCKCHIP) 1051 case SCLK_MAC: 1052 /* select the external clock */ 1053 ret = rk3368_gmac_set_clk(priv->cru, rate); 1054 break; 1055 #endif 1056 case SCLK_SARADC: 1057 ret = rk3368_saradc_set_clk(priv->cru, rate); 1058 break; 1059 #if !defined(CONFIG_SPL_BUILD) 1060 case ACLK_VOP: 1061 case DCLK_VOP: 1062 ret = rk3368_vop_set_clk(priv->cru, clk->id, rate); 1063 break; 1064 case ACLK_CCI_PRE: 1065 ret = 0; 1066 break; 1067 case SCLK_CRYPTO: 1068 ret = rk3368_crypto_set_rate(priv, rate); 1069 break; 1070 #endif 1071 default: 1072 return -ENOENT; 1073 } 1074 1075 return ret; 1076 } 1077 1078 static int __maybe_unused rk3368_gmac_set_parent(struct clk *clk, struct clk *parent) 1079 { 1080 struct rk3368_clk_priv *priv = dev_get_priv(clk->dev); 1081 struct rk3368_cru *cru = priv->cru; 1082 const char *clock_output_name; 1083 int ret; 1084 1085 /* 1086 * If the requested parent is in the same clock-controller and 1087 * the id is SCLK_MAC ("sclk_mac"), switch to the internal 1088 * clock. 1089 */ 1090 if ((parent->dev == clk->dev) && (parent->id == SCLK_MAC)) { 1091 debug("%s: switching GAMC to SCLK_MAC\n", __func__); 1092 rk_clrreg(&cru->clksel_con[43], GMAC_MUX_SEL_EXTCLK); 1093 return 0; 1094 } 1095 1096 /* 1097 * Otherwise, we need to check the clock-output-names of the 1098 * requested parent to see if the requested id is "ext_gmac". 1099 */ 1100 ret = dev_read_string_index(parent->dev, "clock-output-names", 1101 parent->id, &clock_output_name); 1102 if (ret < 0) 1103 return -ENODATA; 1104 1105 /* If this is "ext_gmac", switch to the external clock input */ 1106 if (!strcmp(clock_output_name, "ext_gmac")) { 1107 debug("%s: switching GMAC to external clock\n", __func__); 1108 rk_setreg(&cru->clksel_con[43], GMAC_MUX_SEL_EXTCLK); 1109 return 0; 1110 } 1111 1112 return -EINVAL; 1113 } 1114 1115 static int __maybe_unused rk3368_clk_set_parent(struct clk *clk, struct clk *parent) 1116 { 1117 switch (clk->id) { 1118 case SCLK_MAC: 1119 return rk3368_gmac_set_parent(clk, parent); 1120 } 1121 1122 debug("%s: unsupported clk %ld\n", __func__, clk->id); 1123 return -ENOENT; 1124 } 1125 1126 #define ROCKCHIP_MMC_DELAY_SEL BIT(10) 1127 #define ROCKCHIP_MMC_DEGREE_MASK 0x3 1128 #define ROCKCHIP_MMC_DELAYNUM_OFFSET 2 1129 #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET) 1130 1131 #define PSECS_PER_SEC 1000000000000LL 1132 /* 1133 * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to 1134 * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg. 1135 */ 1136 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60 1137 1138 int rk3368_mmc_get_phase(struct clk *clk) 1139 { 1140 struct rk3368_clk_priv *priv = dev_get_priv(clk->dev); 1141 struct rk3368_cru *cru = priv->cru; 1142 u32 raw_value, delay_num; 1143 u16 degrees = 0; 1144 ulong rate; 1145 1146 rate = rk3368_clk_get_rate(clk); 1147 1148 if (rate < 0) 1149 return rate; 1150 1151 if (clk->id == SCLK_EMMC_SAMPLE) 1152 raw_value = readl(&cru->emmc_con[1]); 1153 else if (clk->id == SCLK_SDMMC_SAMPLE) 1154 raw_value = readl(&cru->sdmmc_con[1]); 1155 else 1156 raw_value = readl(&cru->sdio0_con[1]); 1157 1158 raw_value >>= 1; 1159 degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90; 1160 1161 if (raw_value & ROCKCHIP_MMC_DELAY_SEL) { 1162 /* degrees/delaynum * 10000 */ 1163 unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) * 1164 36 * (rate / 1000000); 1165 1166 delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK); 1167 delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET; 1168 degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000); 1169 } 1170 1171 return degrees % 360; 1172 } 1173 1174 int rk3368_mmc_set_phase(struct clk *clk, u32 degrees) 1175 { 1176 struct rk3368_clk_priv *priv = dev_get_priv(clk->dev); 1177 struct rk3368_cru *cru = priv->cru; 1178 u8 nineties, remainder, delay_num; 1179 u32 raw_value, delay; 1180 ulong rate; 1181 1182 rate = rk3368_clk_get_rate(clk); 1183 1184 if (rate < 0) 1185 return rate; 1186 1187 nineties = degrees / 90; 1188 remainder = (degrees % 90); 1189 1190 /* 1191 * Convert to delay; do a little extra work to make sure we 1192 * don't overflow 32-bit / 64-bit numbers. 1193 */ 1194 delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */ 1195 delay *= remainder; 1196 delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 * 1197 (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10)); 1198 1199 delay_num = (u8)min_t(u32, delay, 255); 1200 1201 raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0; 1202 raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET; 1203 raw_value |= nineties; 1204 1205 raw_value <<= 1; 1206 if (clk->id == SCLK_EMMC_SAMPLE) 1207 writel(raw_value | 0xffff0000, &cru->emmc_con[1]); 1208 else if (clk->id == SCLK_SDMMC_SAMPLE) 1209 writel(raw_value | 0xffff0000, &cru->sdmmc_con[1]); 1210 else 1211 writel(raw_value | 0xffff0000, &cru->sdio0_con[1]); 1212 1213 debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n", 1214 degrees, delay_num, raw_value, rk3368_mmc_get_phase(clk)); 1215 1216 return 0; 1217 } 1218 1219 static int rk3368_clk_get_phase(struct clk *clk) 1220 { 1221 int ret; 1222 1223 debug("%s %ld\n", __func__, clk->id); 1224 switch (clk->id) { 1225 case SCLK_EMMC_SAMPLE: 1226 case SCLK_SDMMC_SAMPLE: 1227 case SCLK_SDIO0_SAMPLE: 1228 ret = rk3368_mmc_get_phase(clk); 1229 break; 1230 default: 1231 return -ENOENT; 1232 } 1233 1234 return ret; 1235 } 1236 1237 static int rk3368_clk_set_phase(struct clk *clk, int degrees) 1238 { 1239 int ret; 1240 1241 debug("%s %ld\n", __func__, clk->id); 1242 switch (clk->id) { 1243 case SCLK_EMMC_SAMPLE: 1244 case SCLK_SDMMC_SAMPLE: 1245 case SCLK_SDIO0_SAMPLE: 1246 ret = rk3368_mmc_set_phase(clk, degrees); 1247 break; 1248 default: 1249 return -ENOENT; 1250 } 1251 1252 return ret; 1253 } 1254 1255 static struct clk_ops rk3368_clk_ops = { 1256 .get_rate = rk3368_clk_get_rate, 1257 .set_rate = rk3368_clk_set_rate, 1258 .get_phase = rk3368_clk_get_phase, 1259 .set_phase = rk3368_clk_set_phase, 1260 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) 1261 .set_parent = rk3368_clk_set_parent, 1262 #endif 1263 }; 1264 1265 #if IS_ENABLED(CONFIG_SPL_BUILD) || IS_ENABLED(CONFIG_TPL_BUILD) 1266 static void rkclk_init(struct rk3368_cru *cru) 1267 { 1268 u32 apllb, aplll, dpll, cpll, gpll; 1269 1270 rkclk_set_pll(cru, APLLB, &apll_b_init_cfg); 1271 rkclk_set_pll(cru, APLLL, &apll_l_init_cfg); 1272 #if !defined(CONFIG_TPL_BUILD) 1273 /* 1274 * If we plan to return to the boot ROM, we can't increase the 1275 * GPLL rate from the SPL stage. 1276 */ 1277 rkclk_set_pll(cru, GPLL, &gpll_init_cfg); 1278 rkclk_set_pll(cru, CPLL, &cpll_init_cfg); 1279 #endif 1280 rk_clrsetreg(&cru->clksel_con[37], (1 << 8), 1 << 8); 1281 apllb = rkclk_pll_get_rate(cru, APLLB); 1282 aplll = rkclk_pll_get_rate(cru, APLLL); 1283 dpll = rkclk_pll_get_rate(cru, DPLL); 1284 cpll = rkclk_pll_get_rate(cru, CPLL); 1285 gpll = rkclk_pll_get_rate(cru, GPLL); 1286 1287 debug("%s apllb(%d) apll(%d) dpll(%d) cpll(%d) gpll(%d)\n", 1288 __func__, apllb, aplll, dpll, cpll, gpll); 1289 } 1290 #endif 1291 1292 static int rk3368_clk_probe(struct udevice *dev) 1293 { 1294 struct rk3368_clk_priv __maybe_unused *priv = dev_get_priv(dev); 1295 int ret; 1296 #if CONFIG_IS_ENABLED(OF_PLATDATA) 1297 struct rk3368_clk_plat *plat = dev_get_platdata(dev); 1298 1299 priv->cru = map_sysmem(plat->dtd.reg[0], plat->dtd.reg[1]); 1300 #endif 1301 priv->sync_kernel = false; 1302 if (!priv->armlclk_enter_hz) 1303 priv->armlclk_enter_hz = rkclk_pll_get_rate(priv->cru, APLLL); 1304 if (!priv->armbclk_enter_hz) 1305 priv->armbclk_enter_hz = rkclk_pll_get_rate(priv->cru, APLLB); 1306 #if IS_ENABLED(CONFIG_SPL_BUILD) || IS_ENABLED(CONFIG_TPL_BUILD) 1307 rkclk_init(priv->cru); 1308 #endif 1309 rkclk_set_pll(priv->cru, NPLL, rkclk_get_pll_config(NPLL_HZ)); 1310 if (!priv->armlclk_init_hz) 1311 priv->armlclk_init_hz = rkclk_pll_get_rate(priv->cru, APLLL); 1312 if (!priv->armbclk_init_hz) 1313 priv->armbclk_init_hz = rkclk_pll_get_rate(priv->cru, APLLB); 1314 /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */ 1315 ret = clk_set_defaults(dev); 1316 if (ret) 1317 debug("%s clk_set_defaults failed %d\n", __func__, ret); 1318 else 1319 priv->sync_kernel = true; 1320 return 0; 1321 } 1322 1323 static int rk3368_clk_ofdata_to_platdata(struct udevice *dev) 1324 { 1325 #if !CONFIG_IS_ENABLED(OF_PLATDATA) 1326 struct rk3368_clk_priv *priv = dev_get_priv(dev); 1327 1328 priv->cru = dev_read_addr_ptr(dev); 1329 #endif 1330 1331 return 0; 1332 } 1333 1334 static int rk3368_clk_bind(struct udevice *dev) 1335 { 1336 int ret; 1337 struct udevice *sys_child, *sf_child; 1338 struct sysreset_reg *priv; 1339 struct softreset_reg *sf_priv; 1340 1341 /* The reset driver does not have a device node, so bind it here */ 1342 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset", 1343 &sys_child); 1344 if (ret) { 1345 debug("Warning: No sysreset driver: ret=%d\n", ret); 1346 } else { 1347 priv = malloc(sizeof(struct sysreset_reg)); 1348 priv->glb_srst_fst_value = offsetof(struct rk3368_cru, 1349 glb_srst_fst_val); 1350 priv->glb_srst_snd_value = offsetof(struct rk3368_cru, 1351 glb_srst_snd_val); 1352 sys_child->priv = priv; 1353 } 1354 1355 ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset", 1356 dev_ofnode(dev), &sf_child); 1357 if (ret) { 1358 debug("Warning: No rockchip reset driver: ret=%d\n", ret); 1359 } else { 1360 sf_priv = malloc(sizeof(struct softreset_reg)); 1361 sf_priv->sf_reset_offset = offsetof(struct rk3368_cru, 1362 softrst_con[0]); 1363 sf_priv->sf_reset_num = 15; 1364 sf_child->priv = sf_priv; 1365 } 1366 1367 return 0; 1368 } 1369 1370 static const struct udevice_id rk3368_clk_ids[] = { 1371 { .compatible = "rockchip,rk3368-cru" }, 1372 { } 1373 }; 1374 1375 U_BOOT_DRIVER(rockchip_rk3368_cru) = { 1376 .name = "rockchip_rk3368_cru", 1377 .id = UCLASS_CLK, 1378 .of_match = rk3368_clk_ids, 1379 .priv_auto_alloc_size = sizeof(struct rk3368_clk_priv), 1380 #if CONFIG_IS_ENABLED(OF_PLATDATA) 1381 .platdata_auto_alloc_size = sizeof(struct rk3368_clk_plat), 1382 #endif 1383 .ofdata_to_platdata = rk3368_clk_ofdata_to_platdata, 1384 .ops = &rk3368_clk_ops, 1385 .bind = rk3368_clk_bind, 1386 .probe = rk3368_clk_probe, 1387 }; 1388 1389 #if !defined(CONFIG_SPL_BUILD) 1390 /** 1391 * soc_clk_dump() - Print clock frequencies 1392 * Returns zero on success 1393 * 1394 * Implementation for the clk dump command. 1395 */ 1396 int soc_clk_dump(void) 1397 { 1398 struct udevice *cru_dev; 1399 struct rk3368_clk_priv *priv; 1400 const struct rk3368_clk_info *clk_dump; 1401 struct clk clk; 1402 unsigned long clk_count = ARRAY_SIZE(clks_dump); 1403 unsigned long rate; 1404 int i, ret; 1405 1406 ret = uclass_get_device_by_driver(UCLASS_CLK, 1407 DM_GET_DRIVER(rockchip_rk3368_cru), 1408 &cru_dev); 1409 if (ret) { 1410 printf("%s failed to get cru device\n", __func__); 1411 return ret; 1412 } 1413 1414 priv = dev_get_priv(cru_dev); 1415 printf("CLK: (%s. arml: enter %lu KHz, init %lu KHz, kernel %lu%s)\n", 1416 priv->sync_kernel ? "sync kernel" : "uboot", 1417 priv->armlclk_enter_hz / 1000, 1418 priv->armlclk_init_hz / 1000, 1419 priv->set_armclk_rate ? priv->armlclk_hz / 1000 : 0, 1420 priv->set_armclk_rate ? " KHz" : "N/A"); 1421 printf("CLK: (%s. armb: enter %lu KHz, init %lu KHz, kernel %lu%s)\n", 1422 priv->sync_kernel ? "sync kernel" : "uboot", 1423 priv->armbclk_enter_hz / 1000, 1424 priv->armbclk_init_hz / 1000, 1425 priv->set_armclk_rate ? priv->armlclk_hz / 1000 : 0, 1426 priv->set_armclk_rate ? " KHz" : "N/A"); 1427 for (i = 0; i < clk_count; i++) { 1428 clk_dump = &clks_dump[i]; 1429 if (clk_dump->name) { 1430 clk.id = clk_dump->id; 1431 if (clk_dump->is_cru) 1432 ret = clk_request(cru_dev, &clk); 1433 if (ret < 0) 1434 return ret; 1435 1436 rate = clk_get_rate(&clk); 1437 clk_free(&clk); 1438 if (i == 0) { 1439 if (rate < 0) 1440 printf(" %s %s\n", clk_dump->name, 1441 "unknown"); 1442 else 1443 printf(" %s %lu KHz\n", clk_dump->name, 1444 rate / 1000); 1445 } else { 1446 if (rate < 0) 1447 printf(" %s %s\n", clk_dump->name, 1448 "unknown"); 1449 else 1450 printf(" %s %lu KHz\n", clk_dump->name, 1451 rate / 1000); 1452 } 1453 } 1454 } 1455 1456 return 0; 1457 } 1458 #endif 1459