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