1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd 4 * Author: Finley Xiao <finley.xiao@rock-chips.com> 5 */ 6 7 #include <common.h> 8 #include <bitfield.h> 9 #include <clk-uclass.h> 10 #include <dm.h> 11 #include <errno.h> 12 #include <syscon.h> 13 #include <asm/arch/clock.h> 14 #include <asm/arch/cru_rv1126.h> 15 #include <asm/arch/grf_rv1126.h> 16 #include <asm/arch/hardware.h> 17 #include <asm/io.h> 18 #include <dm/lists.h> 19 #include <dt-bindings/clock/rv1126-cru.h> 20 21 DECLARE_GLOBAL_DATA_PTR; 22 23 #define RV1126_CPUCLK_RATE(_rate, _aclk_div, _pclk_div) \ 24 { \ 25 .rate = _rate##U, \ 26 .aclk_div = _aclk_div, \ 27 .pclk_div = _pclk_div, \ 28 } 29 30 #define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1)) 31 32 static struct rockchip_cpu_rate_table rv1126_cpu_rates[] = { 33 RV1126_CPUCLK_RATE(1200000000, 1, 5), 34 RV1126_CPUCLK_RATE(1008000000, 1, 5), 35 RV1126_CPUCLK_RATE(816000000, 1, 3), 36 RV1126_CPUCLK_RATE(600000000, 1, 3), 37 RV1126_CPUCLK_RATE(408000000, 1, 1), 38 }; 39 40 static struct rockchip_pll_rate_table rv1126_pll_rates[] = { 41 /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */ 42 RK3036_PLL_RATE(1600000000, 3, 200, 1, 1, 1, 0), 43 RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0), 44 RK3036_PLL_RATE(1188000000, 2, 99, 1, 1, 1, 0), 45 RK3036_PLL_RATE(1100000000, 12, 550, 1, 1, 1, 0), 46 RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0), 47 RK3036_PLL_RATE(1000000000, 6, 500, 2, 1, 1, 0), 48 RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0), 49 RK3036_PLL_RATE(800000000, 6, 400, 2, 1, 1, 0), 50 RK3036_PLL_RATE(600000000, 1, 75, 3, 1, 1, 0), 51 RK3036_PLL_RATE(594000000, 2, 99, 2, 1, 1, 0), 52 RK3036_PLL_RATE(500000000, 6, 250, 2, 1, 1, 0), 53 RK3036_PLL_RATE(200000000, 1, 200, 6, 4, 1, 0), 54 RK3036_PLL_RATE(100000000, 1, 150, 6, 6, 1, 0), 55 { /* sentinel */ }, 56 }; 57 58 static struct rockchip_pll_clock rv1126_pll_clks[] = { 59 [APLL] = PLL(pll_rk3328, PLL_APLL, RV1126_PLL_CON(0), 60 RV1126_MODE_CON, 0, 10, 0, rv1126_pll_rates), 61 [DPLL] = PLL(pll_rk3328, PLL_DPLL, RV1126_PLL_CON(8), 62 RV1126_MODE_CON, 2, 10, 0, NULL), 63 [CPLL] = PLL(pll_rk3328, PLL_CPLL, RV1126_PLL_CON(16), 64 RV1126_MODE_CON, 4, 10, 0, rv1126_pll_rates), 65 [HPLL] = PLL(pll_rk3328, PLL_HPLL, RV1126_PLL_CON(24), 66 RV1126_MODE_CON, 6, 10, 0, rv1126_pll_rates), 67 [GPLL] = PLL(pll_rk3328, PLL_GPLL, RV1126_PMU_PLL_CON(0), 68 RV1126_PMU_MODE, 0, 10, 0, rv1126_pll_rates), 69 }; 70 71 #ifndef CONFIG_SPL_BUILD 72 #define RV1126_CLK_DUMP(_id, _name, _iscru) \ 73 { \ 74 .id = _id, \ 75 .name = _name, \ 76 .is_cru = _iscru, \ 77 } 78 79 static const struct rv1126_clk_info clks_dump[] = { 80 RV1126_CLK_DUMP(PLL_APLL, "apll", true), 81 RV1126_CLK_DUMP(PLL_DPLL, "dpll", true), 82 RV1126_CLK_DUMP(PLL_GPLL, "gpll", false), 83 RV1126_CLK_DUMP(PLL_CPLL, "cpll", true), 84 RV1126_CLK_DUMP(PLL_HPLL, "hpll", true), 85 RV1126_CLK_DUMP(ACLK_PDBUS, "aclk_pdbus", true), 86 RV1126_CLK_DUMP(HCLK_PDBUS, "hclk_pdbus", true), 87 RV1126_CLK_DUMP(PCLK_PDBUS, "pclk_pdbus", true), 88 RV1126_CLK_DUMP(ACLK_PDPHP, "aclk_pdphp", true), 89 RV1126_CLK_DUMP(HCLK_PDPHP, "hclk_pdphp", true), 90 RV1126_CLK_DUMP(HCLK_PDAUDIO, "hclk_pdaudio", true), 91 RV1126_CLK_DUMP(HCLK_PDCORE_NIU, "hclk_pdcore", true), 92 RV1126_CLK_DUMP(PCLK_PDPMU, "pclk_pdpmu", false), 93 }; 94 #endif 95 96 static ulong rv1126_gpll_set_rate(struct rv1126_clk_priv *priv, 97 struct rv1126_pmuclk_priv *pmu_priv, 98 ulong rate); 99 /* 100 * 101 * rational_best_approximation(31415, 10000, 102 * (1 << 8) - 1, (1 << 5) - 1, &n, &d); 103 * 104 * you may look at given_numerator as a fixed point number, 105 * with the fractional part size described in given_denominator. 106 * 107 * for theoretical background, see: 108 * http://en.wikipedia.org/wiki/Continued_fraction 109 */ 110 static void rational_best_approximation(unsigned long given_numerator, 111 unsigned long given_denominator, 112 unsigned long max_numerator, 113 unsigned long max_denominator, 114 unsigned long *best_numerator, 115 unsigned long *best_denominator) 116 { 117 unsigned long n, d, n0, d0, n1, d1; 118 119 n = given_numerator; 120 d = given_denominator; 121 n0 = 0; 122 d1 = 0; 123 n1 = 1; 124 d0 = 1; 125 for (;;) { 126 unsigned long t, a; 127 128 if (n1 > max_numerator || d1 > max_denominator) { 129 n1 = n0; 130 d1 = d0; 131 break; 132 } 133 if (d == 0) 134 break; 135 t = d; 136 a = n / d; 137 d = n % d; 138 n = t; 139 t = n0 + a * n1; 140 n0 = n1; 141 n1 = t; 142 t = d0 + a * d1; 143 d0 = d1; 144 d1 = t; 145 } 146 *best_numerator = n1; 147 *best_denominator = d1; 148 } 149 150 static ulong rv1126_gpll_get_pmuclk(struct rv1126_pmuclk_priv *priv) 151 { 152 return rockchip_pll_get_rate(&rv1126_pll_clks[GPLL], 153 priv->pmucru, GPLL); 154 } 155 156 static ulong rv1126_gpll_set_pmuclk(struct rv1126_pmuclk_priv *pmu_priv, ulong rate) 157 { 158 struct udevice *cru_dev; 159 struct rv1126_clk_priv *priv; 160 int ret; 161 162 ret = uclass_get_device_by_driver(UCLASS_CLK, 163 DM_GET_DRIVER(rockchip_rv1126_cru), 164 &cru_dev); 165 if (ret) { 166 printf("%s: could not find cru device\n", __func__); 167 return ret; 168 } 169 priv = dev_get_priv(cru_dev); 170 171 if (rv1126_gpll_set_rate(priv, pmu_priv, rate)) { 172 printf("%s: failed to set gpll rate %lu\n", __func__, rate); 173 return -EINVAL; 174 } 175 return 0; 176 } 177 178 static ulong rv1126_rtc32k_get_pmuclk(struct rv1126_pmuclk_priv *priv) 179 { 180 struct rv1126_pmucru *pmucru = priv->pmucru; 181 unsigned long m, n; 182 u32 fracdiv; 183 184 fracdiv = readl(&pmucru->pmu_clksel_con[13]); 185 m = fracdiv & CLK_RTC32K_FRAC_NUMERATOR_MASK; 186 m >>= CLK_RTC32K_FRAC_NUMERATOR_SHIFT; 187 n = fracdiv & CLK_RTC32K_FRAC_DENOMINATOR_MASK; 188 n >>= CLK_RTC32K_FRAC_DENOMINATOR_SHIFT; 189 190 return OSC_HZ * m / n; 191 } 192 193 static ulong rv1126_rtc32k_set_pmuclk(struct rv1126_pmuclk_priv *priv, 194 ulong rate) 195 { 196 struct rv1126_pmucru *pmucru = priv->pmucru; 197 unsigned long m, n, val; 198 199 rational_best_approximation(rate, OSC_HZ, 200 GENMASK(16 - 1, 0), 201 GENMASK(16 - 1, 0), 202 &m, &n); 203 val = m << CLK_RTC32K_FRAC_NUMERATOR_SHIFT | n; 204 writel(val, &pmucru->pmu_clksel_con[13]); 205 206 return rv1126_rtc32k_get_pmuclk(priv); 207 } 208 209 static ulong rv1126_i2c_get_pmuclk(struct rv1126_pmuclk_priv *priv, 210 ulong clk_id) 211 { 212 struct rv1126_pmucru *pmucru = priv->pmucru; 213 u32 div, con; 214 215 switch (clk_id) { 216 case CLK_I2C0: 217 con = readl(&pmucru->pmu_clksel_con[2]); 218 div = (con & CLK_I2C0_DIV_MASK) >> CLK_I2C0_DIV_SHIFT; 219 break; 220 case CLK_I2C2: 221 con = readl(&pmucru->pmu_clksel_con[3]); 222 div = (con & CLK_I2C1_DIV_MASK) >> CLK_I2C1_DIV_SHIFT; 223 break; 224 default: 225 return -ENOENT; 226 } 227 228 return DIV_TO_RATE(priv->gpll_hz, div); 229 } 230 231 static ulong rv1126_i2c_set_pmuclk(struct rv1126_pmuclk_priv *priv, 232 ulong clk_id, ulong rate) 233 { 234 struct rv1126_pmucru *pmucru = priv->pmucru; 235 int src_clk_div; 236 237 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); 238 assert(src_clk_div - 1 <= 127); 239 240 switch (clk_id) { 241 case CLK_I2C0: 242 rk_clrsetreg(&pmucru->pmu_clksel_con[2], CLK_I2C0_DIV_MASK, 243 (src_clk_div - 1) << CLK_I2C0_DIV_SHIFT); 244 break; 245 case CLK_I2C2: 246 rk_clrsetreg(&pmucru->pmu_clksel_con[3], CLK_I2C2_DIV_MASK, 247 (src_clk_div - 1) << CLK_I2C2_DIV_SHIFT); 248 break; 249 default: 250 return -ENOENT; 251 } 252 253 return rv1126_i2c_get_pmuclk(priv, clk_id); 254 } 255 256 static ulong rv1126_pwm_get_pmuclk(struct rv1126_pmuclk_priv *priv, 257 ulong clk_id) 258 { 259 struct rv1126_pmucru *pmucru = priv->pmucru; 260 u32 div, sel, con; 261 262 switch (clk_id) { 263 case CLK_PWM0: 264 con = readl(&pmucru->pmu_clksel_con[6]); 265 sel = (con & CLK_PWM0_SEL_MASK) >> CLK_PWM0_SEL_SHIFT; 266 div = (con & CLK_PWM0_DIV_MASK) >> CLK_PWM0_DIV_SHIFT; 267 if (sel == CLK_PWM0_SEL_XIN24M) 268 return OSC_HZ; 269 break; 270 case CLK_PWM1: 271 con = readl(&pmucru->pmu_clksel_con[6]); 272 sel = (con & CLK_PWM1_SEL_MASK) >> CLK_PWM1_SEL_SHIFT; 273 div = (con & CLK_PWM1_DIV_MASK) >> CLK_PWM1_DIV_SHIFT; 274 if (sel == CLK_PWM1_SEL_XIN24M) 275 return OSC_HZ; 276 break; 277 default: 278 return -ENOENT; 279 } 280 281 return DIV_TO_RATE(priv->gpll_hz, div); 282 } 283 284 static ulong rv1126_pwm_set_pmuclk(struct rv1126_pmuclk_priv *priv, 285 ulong clk_id, ulong rate) 286 { 287 struct rv1126_pmucru *pmucru = priv->pmucru; 288 int src_clk_div; 289 290 switch (clk_id) { 291 case CLK_PWM0: 292 if (rate == OSC_HZ) { 293 rk_clrsetreg(&pmucru->pmu_clksel_con[6], 294 CLK_PWM0_SEL_MASK, 295 CLK_PWM0_SEL_XIN24M << CLK_PWM0_SEL_SHIFT); 296 rk_clrsetreg(&pmucru->pmu_clksel_con[6], 297 CLK_PWM0_DIV_MASK, 0); 298 } else { 299 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); 300 assert(src_clk_div - 1 <= 127); 301 rk_clrsetreg(&pmucru->pmu_clksel_con[6], 302 CLK_PWM0_DIV_MASK, 303 (src_clk_div - 1) << CLK_PWM0_DIV_SHIFT); 304 rk_clrsetreg(&pmucru->pmu_clksel_con[6], 305 CLK_PWM0_SEL_MASK, 306 CLK_PWM0_SEL_GPLL << CLK_PWM0_SEL_SHIFT); 307 } 308 break; 309 case CLK_PWM1: 310 if (rate == OSC_HZ) { 311 rk_clrsetreg(&pmucru->pmu_clksel_con[6], 312 CLK_PWM1_SEL_MASK, 313 CLK_PWM1_SEL_XIN24M << CLK_PWM1_SEL_SHIFT); 314 rk_clrsetreg(&pmucru->pmu_clksel_con[6], 315 CLK_PWM1_DIV_MASK, 0); 316 } else { 317 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); 318 assert(src_clk_div - 1 <= 127); 319 rk_clrsetreg(&pmucru->pmu_clksel_con[6], 320 CLK_PWM1_DIV_MASK, 321 (src_clk_div - 1) << CLK_PWM1_DIV_SHIFT); 322 rk_clrsetreg(&pmucru->pmu_clksel_con[6], 323 CLK_PWM1_SEL_MASK, 324 CLK_PWM1_SEL_GPLL << CLK_PWM1_SEL_SHIFT); 325 } 326 break; 327 default: 328 return -ENOENT; 329 } 330 331 return rv1126_pwm_get_pmuclk(priv, clk_id); 332 } 333 334 static ulong rv1126_spi_get_pmuclk(struct rv1126_pmuclk_priv *priv) 335 { 336 struct rv1126_pmucru *pmucru = priv->pmucru; 337 u32 div, con; 338 339 con = readl(&pmucru->pmu_clksel_con[9]); 340 div = (con & CLK_SPI0_DIV_MASK) >> CLK_SPI0_DIV_SHIFT; 341 342 return DIV_TO_RATE(priv->gpll_hz, div); 343 } 344 345 static ulong rv1126_spi_set_pmuclk(struct rv1126_pmuclk_priv *priv, 346 ulong rate) 347 { 348 struct rv1126_pmucru *pmucru = priv->pmucru; 349 int src_clk_div; 350 351 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); 352 assert(src_clk_div - 1 <= 127); 353 354 rk_clrsetreg(&pmucru->pmu_clksel_con[9], 355 CLK_SPI0_SEL_MASK | CLK_SPI0_DIV_MASK, 356 CLK_SPI0_SEL_GPLL << CLK_SPI0_SEL_SHIFT | 357 (src_clk_div - 1) << CLK_SPI0_DIV_SHIFT); 358 359 return rv1126_spi_get_pmuclk(priv); 360 } 361 362 static ulong rv1126_pdpmu_get_pmuclk(struct rv1126_pmuclk_priv *priv) 363 { 364 struct rv1126_pmucru *pmucru = priv->pmucru; 365 u32 div, con; 366 367 con = readl(&pmucru->pmu_clksel_con[1]); 368 div = (con & PCLK_PDPMU_DIV_MASK) >> PCLK_PDPMU_DIV_SHIFT; 369 370 return DIV_TO_RATE(priv->gpll_hz, div); 371 } 372 373 static ulong rv1126_pdpmu_set_pmuclk(struct rv1126_pmuclk_priv *priv, 374 ulong rate) 375 { 376 struct rv1126_pmucru *pmucru = priv->pmucru; 377 int src_clk_div; 378 379 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); 380 assert(src_clk_div - 1 <= 31); 381 382 rk_clrsetreg(&pmucru->pmu_clksel_con[1], 383 PCLK_PDPMU_DIV_MASK, 384 (src_clk_div - 1) << PCLK_PDPMU_DIV_SHIFT); 385 386 return rv1126_pdpmu_get_pmuclk(priv); 387 } 388 389 static ulong rv1126_pmuclk_get_rate(struct clk *clk) 390 { 391 struct rv1126_pmuclk_priv *priv = dev_get_priv(clk->dev); 392 ulong rate = 0; 393 394 if (!priv->gpll_hz) { 395 printf("%s gpll=%lu\n", __func__, priv->gpll_hz); 396 return -ENOENT; 397 } 398 399 debug("%s %ld\n", __func__, clk->id); 400 switch (clk->id) { 401 case PLL_GPLL: 402 rate = rv1126_gpll_get_pmuclk(priv); 403 break; 404 case CLK_RTC32K: 405 rate = rv1126_rtc32k_get_pmuclk(priv); 406 break; 407 case CLK_I2C0: 408 case CLK_I2C2: 409 rate = rv1126_i2c_get_pmuclk(priv, clk->id); 410 break; 411 case CLK_PWM0: 412 case CLK_PWM1: 413 rate = rv1126_pwm_get_pmuclk(priv, clk->id); 414 break; 415 case CLK_SPI0: 416 rate = rv1126_spi_get_pmuclk(priv); 417 break; 418 case PCLK_PDPMU: 419 rate = rv1126_pdpmu_get_pmuclk(priv); 420 break; 421 default: 422 return -ENOENT; 423 } 424 425 return rate; 426 } 427 428 static ulong rv1126_pmuclk_set_rate(struct clk *clk, ulong rate) 429 { 430 struct rv1126_pmuclk_priv *priv = dev_get_priv(clk->dev); 431 ulong ret = 0; 432 433 if (!priv->gpll_hz) { 434 printf("%s gpll=%lu\n", __func__, priv->gpll_hz); 435 return -ENOENT; 436 } 437 438 debug("%s %ld %ld\n", __func__, clk->id, rate); 439 switch (clk->id) { 440 case PLL_GPLL: 441 ret = rv1126_gpll_set_pmuclk(priv, rate); 442 break; 443 case CLK_RTC32K: 444 ret = rv1126_rtc32k_set_pmuclk(priv, rate); 445 break; 446 case CLK_I2C0: 447 case CLK_I2C2: 448 ret = rv1126_i2c_set_pmuclk(priv, clk->id, rate); 449 break; 450 case CLK_PWM0: 451 case CLK_PWM1: 452 ret = rv1126_pwm_set_pmuclk(priv, clk->id, rate); 453 break; 454 case CLK_SPI0: 455 ret = rv1126_spi_set_pmuclk(priv, rate); 456 break; 457 case PCLK_PDPMU: 458 ret = rv1126_pdpmu_set_pmuclk(priv, rate); 459 break; 460 default: 461 return -ENOENT; 462 } 463 464 return ret; 465 } 466 467 static int rv1126_rtc32k_set_parent(struct clk *clk, struct clk *parent) 468 { 469 struct rv1126_pmuclk_priv *priv = dev_get_priv(clk->dev); 470 struct rv1126_pmucru *pmucru = priv->pmucru; 471 472 if (parent->id == CLK_OSC0_DIV32K) 473 rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK, 474 RTC32K_SEL_OSC0_DIV32K << RTC32K_SEL_SHIFT); 475 else 476 rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK, 477 RTC32K_SEL_OSC1_32K << RTC32K_SEL_SHIFT); 478 479 return 0; 480 } 481 482 static int rv1126_pmuclk_set_parent(struct clk *clk, struct clk *parent) 483 { 484 switch (clk->id) { 485 case CLK_RTC32K: 486 return rv1126_rtc32k_set_parent(clk, parent); 487 default: 488 return -ENOENT; 489 } 490 } 491 static struct clk_ops rv1126_pmuclk_ops = { 492 .get_rate = rv1126_pmuclk_get_rate, 493 .set_rate = rv1126_pmuclk_set_rate, 494 .set_parent = rv1126_pmuclk_set_parent, 495 }; 496 497 static int rv1126_pmuclk_probe(struct udevice *dev) 498 { 499 struct rv1126_pmuclk_priv *priv = dev_get_priv(dev); 500 501 priv->gpll_hz = rv1126_gpll_get_pmuclk(priv); 502 503 return 0; 504 } 505 506 static int rv1126_pmuclk_ofdata_to_platdata(struct udevice *dev) 507 { 508 struct rv1126_pmuclk_priv *priv = dev_get_priv(dev); 509 510 priv->pmucru = dev_read_addr_ptr(dev); 511 512 return 0; 513 } 514 515 static int rv1126_pmuclk_bind(struct udevice *dev) 516 { 517 int ret = 0; 518 struct udevice *sf_child; 519 struct softreset_reg *sf_priv; 520 521 ret = device_bind_driver_to_node(dev, "rockchip_reset", 522 "reset", dev_ofnode(dev), 523 &sf_child); 524 if (ret) { 525 debug("Warning: No rockchip reset driver: ret=%d\n", ret); 526 } else { 527 sf_priv = malloc(sizeof(struct softreset_reg)); 528 sf_priv->sf_reset_offset = offsetof(struct rv1126_pmucru, 529 pmu_softrst_con[0]); 530 sf_priv->sf_reset_num = 2; 531 sf_child->priv = sf_priv; 532 } 533 534 return 0; 535 } 536 537 static const struct udevice_id rv1126_pmuclk_ids[] = { 538 { .compatible = "rockchip,rv1126-pmucru" }, 539 { } 540 }; 541 542 U_BOOT_DRIVER(rockchip_rv1126_pmucru) = { 543 .name = "rockchip_rv1126_pmucru", 544 .id = UCLASS_CLK, 545 .of_match = rv1126_pmuclk_ids, 546 .priv_auto_alloc_size = sizeof(struct rv1126_pmuclk_priv), 547 .ofdata_to_platdata = rv1126_pmuclk_ofdata_to_platdata, 548 .ops = &rv1126_pmuclk_ops, 549 .bind = rv1126_pmuclk_bind, 550 .probe = rv1126_pmuclk_probe, 551 }; 552 553 554 static int rv1126_armclk_set_clk(struct rv1126_clk_priv *priv, ulong hz) 555 { 556 struct rv1126_cru *cru = priv->cru; 557 const struct rockchip_cpu_rate_table *rate; 558 ulong old_rate; 559 560 rate = rockchip_get_cpu_settings(rv1126_cpu_rates, hz); 561 if (!rate) { 562 printf("%s unsupported rate\n", __func__); 563 return -EINVAL; 564 } 565 566 /* 567 * set up dependent divisors for DBG and ACLK clocks. 568 */ 569 old_rate = rockchip_pll_get_rate(&rv1126_pll_clks[APLL], 570 priv->cru, APLL); 571 if (old_rate > hz) { 572 if (rockchip_pll_set_rate(&rv1126_pll_clks[APLL], 573 priv->cru, APLL, hz)) 574 return -EINVAL; 575 rk_clrsetreg(&cru->clksel_con[1], 576 CORE_DBG_DIV_MASK | CORE_ACLK_DIV_MASK, 577 rate->pclk_div << CORE_DBG_DIV_SHIFT | 578 rate->aclk_div << CORE_ACLK_DIV_SHIFT); 579 } else if (old_rate < hz) { 580 rk_clrsetreg(&cru->clksel_con[1], 581 CORE_DBG_DIV_MASK | CORE_ACLK_DIV_MASK, 582 rate->pclk_div << CORE_DBG_DIV_SHIFT | 583 rate->aclk_div << CORE_ACLK_DIV_SHIFT); 584 if (rockchip_pll_set_rate(&rv1126_pll_clks[APLL], 585 priv->cru, APLL, hz)) 586 return -EINVAL; 587 } 588 589 return 0; 590 } 591 592 static ulong rv1126_pdcore_get_clk(struct rv1126_clk_priv *priv) 593 { 594 struct rv1126_cru *cru = priv->cru; 595 u32 con, div; 596 597 con = readl(&cru->clksel_con[0]); 598 div = (con & CORE_HCLK_DIV_MASK) >> CORE_HCLK_DIV_SHIFT; 599 600 return DIV_TO_RATE(priv->gpll_hz, div); 601 } 602 603 static ulong rv1126_pdcore_set_clk(struct rv1126_clk_priv *priv, ulong rate) 604 { 605 struct rv1126_cru *cru = priv->cru; 606 int src_clk_div; 607 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); 608 assert(src_clk_div - 1 <= 31); 609 610 rk_clrsetreg(&cru->clksel_con[0], CORE_HCLK_DIV_MASK, 611 (src_clk_div - 1) << CORE_HCLK_DIV_SHIFT); 612 613 return rv1126_pdcore_get_clk(priv); 614 } 615 616 static ulong rv1126_pdbus_get_clk(struct rv1126_clk_priv *priv, ulong clk_id) 617 { 618 struct rv1126_cru *cru = priv->cru; 619 u32 con, div, sel, parent; 620 621 switch (clk_id) { 622 case ACLK_PDBUS: 623 con = readl(&cru->clksel_con[2]); 624 div = (con & ACLK_PDBUS_DIV_MASK) >> ACLK_PDBUS_DIV_SHIFT; 625 sel = (con & ACLK_PDBUS_SEL_MASK) >> ACLK_PDBUS_SEL_SHIFT; 626 if (sel == ACLK_PDBUS_SEL_GPLL) 627 parent = priv->gpll_hz; 628 else if (sel == ACLK_PDBUS_SEL_CPLL) 629 parent = priv->cpll_hz; 630 else 631 return -ENOENT; 632 break; 633 case HCLK_PDBUS: 634 con = readl(&cru->clksel_con[2]); 635 div = (con & HCLK_PDBUS_DIV_MASK) >> HCLK_PDBUS_DIV_SHIFT; 636 sel = (con & HCLK_PDBUS_SEL_MASK) >> HCLK_PDBUS_SEL_SHIFT; 637 if (sel == HCLK_PDBUS_SEL_GPLL) 638 parent = priv->gpll_hz; 639 else if (sel == HCLK_PDBUS_SEL_CPLL) 640 parent = priv->cpll_hz; 641 else 642 return -ENOENT; 643 break; 644 case PCLK_PDBUS: 645 con = readl(&cru->clksel_con[3]); 646 div = (con & PCLK_PDBUS_DIV_MASK) >> PCLK_PDBUS_DIV_SHIFT; 647 sel = (con & PCLK_PDBUS_SEL_MASK) >> PCLK_PDBUS_SEL_SHIFT; 648 if (sel == PCLK_PDBUS_SEL_GPLL) 649 parent = priv->gpll_hz; 650 else if (sel == PCLK_PDBUS_SEL_CPLL) 651 parent = priv->cpll_hz; 652 else 653 return -ENOENT; 654 break; 655 default: 656 return -ENOENT; 657 } 658 659 return DIV_TO_RATE(parent, div); 660 } 661 662 static ulong rv1126_pdbus_set_clk(struct rv1126_clk_priv *priv, ulong clk_id, 663 ulong rate) 664 { 665 struct rv1126_cru *cru = priv->cru; 666 int src_clk_div; 667 668 switch (clk_id) { 669 case ACLK_PDBUS: 670 src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate); 671 assert(src_clk_div - 1 <= 31); 672 rk_clrsetreg(&cru->clksel_con[2], 673 ACLK_PDBUS_SEL_MASK | ACLK_PDBUS_DIV_MASK, 674 ACLK_PDBUS_SEL_CPLL << ACLK_PDBUS_SEL_SHIFT | 675 (src_clk_div - 1) << ACLK_PDBUS_DIV_SHIFT); 676 break; 677 case HCLK_PDBUS: 678 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); 679 assert(src_clk_div - 1 <= 31); 680 rk_clrsetreg(&cru->clksel_con[2], 681 HCLK_PDBUS_SEL_MASK | HCLK_PDBUS_DIV_MASK, 682 HCLK_PDBUS_SEL_GPLL << HCLK_PDBUS_SEL_SHIFT | 683 (src_clk_div - 1) << HCLK_PDBUS_DIV_SHIFT); 684 break; 685 case PCLK_PDBUS: 686 src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate); 687 assert(src_clk_div - 1 <= 31); 688 rk_clrsetreg(&cru->clksel_con[3], 689 PCLK_PDBUS_SEL_MASK | PCLK_PDBUS_DIV_MASK, 690 PCLK_PDBUS_SEL_CPLL << PCLK_PDBUS_SEL_SHIFT | 691 (src_clk_div - 1) << PCLK_PDBUS_DIV_SHIFT); 692 break; 693 694 default: 695 printf("do not support this pdbus freq\n"); 696 return -EINVAL; 697 } 698 699 return rv1126_pdbus_get_clk(priv, clk_id); 700 } 701 702 static ulong rv1126_pdphp_get_clk(struct rv1126_clk_priv *priv, ulong clk_id) 703 { 704 struct rv1126_cru *cru = priv->cru; 705 u32 con, div, parent; 706 707 switch (clk_id) { 708 case ACLK_PDPHP: 709 con = readl(&cru->clksel_con[53]); 710 div = (con & ACLK_PDPHP_DIV_MASK) >> ACLK_PDPHP_DIV_SHIFT; 711 parent = priv->gpll_hz; 712 break; 713 case HCLK_PDPHP: 714 con = readl(&cru->clksel_con[53]); 715 div = (con & HCLK_PDPHP_DIV_MASK) >> HCLK_PDPHP_DIV_SHIFT; 716 parent = priv->gpll_hz; 717 break; 718 default: 719 return -ENOENT; 720 } 721 722 return DIV_TO_RATE(parent, div); 723 } 724 725 static ulong rv1126_pdphp_set_clk(struct rv1126_clk_priv *priv, ulong clk_id, 726 ulong rate) 727 { 728 struct rv1126_cru *cru = priv->cru; 729 int src_clk_div; 730 731 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); 732 assert(src_clk_div - 1 <= 31); 733 734 switch (clk_id) { 735 case ACLK_PDPHP: 736 rk_clrsetreg(&cru->clksel_con[53], 737 ACLK_PDPHP_SEL_MASK | ACLK_PDPHP_DIV_MASK, 738 ACLK_PDPHP_SEL_GPLL << ACLK_PDPHP_SEL_SHIFT | 739 (src_clk_div - 1) << ACLK_PDPHP_DIV_SHIFT); 740 break; 741 case HCLK_PDPHP: 742 rk_clrsetreg(&cru->clksel_con[53], 743 HCLK_PDPHP_DIV_MASK, 744 (src_clk_div - 1) << HCLK_PDPHP_DIV_SHIFT); 745 break; 746 default: 747 printf("do not support this pdphp freq\n"); 748 return -EINVAL; 749 } 750 751 return rv1126_pdphp_get_clk(priv, clk_id); 752 } 753 754 static ulong rv1126_pdaudio_get_clk(struct rv1126_clk_priv *priv) 755 { 756 struct rv1126_cru *cru = priv->cru; 757 u32 con, div; 758 759 con = readl(&cru->clksel_con[26]); 760 div = (con & HCLK_PDAUDIO_DIV_MASK) >> HCLK_PDAUDIO_DIV_SHIFT; 761 762 return DIV_TO_RATE(priv->gpll_hz, div); 763 } 764 765 static ulong rv1126_pdaudio_set_clk(struct rv1126_clk_priv *priv, ulong rate) 766 { 767 struct rv1126_cru *cru = priv->cru; 768 int src_clk_div; 769 770 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); 771 assert(src_clk_div - 1 <= 31); 772 773 rk_clrsetreg(&cru->clksel_con[26], HCLK_PDAUDIO_DIV_MASK, 774 (src_clk_div - 1) << HCLK_PDAUDIO_DIV_SHIFT); 775 776 return rv1126_pdaudio_get_clk(priv); 777 } 778 779 static ulong rv1126_i2c_get_clk(struct rv1126_clk_priv *priv, ulong clk_id) 780 { 781 struct rv1126_cru *cru = priv->cru; 782 u32 div, con; 783 784 switch (clk_id) { 785 case CLK_I2C1: 786 con = readl(&cru->clksel_con[5]); 787 div = (con & CLK_I2C1_DIV_MASK) >> CLK_I2C1_DIV_SHIFT; 788 break; 789 case CLK_I2C3: 790 con = readl(&cru->clksel_con[5]); 791 div = (con & CLK_I2C3_DIV_MASK) >> CLK_I2C3_DIV_SHIFT; 792 break; 793 case CLK_I2C4: 794 con = readl(&cru->clksel_con[6]); 795 div = (con & CLK_I2C4_DIV_MASK) >> CLK_I2C4_DIV_SHIFT; 796 break; 797 case CLK_I2C5: 798 con = readl(&cru->clksel_con[6]); 799 div = (con & CLK_I2C5_DIV_MASK) >> CLK_I2C5_DIV_SHIFT; 800 break; 801 default: 802 return -ENOENT; 803 } 804 805 return DIV_TO_RATE(priv->gpll_hz, div); 806 } 807 808 static ulong rv1126_i2c_set_clk(struct rv1126_clk_priv *priv, ulong clk_id, 809 ulong rate) 810 { 811 struct rv1126_cru *cru = priv->cru; 812 int src_clk_div; 813 814 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); 815 assert(src_clk_div - 1 <= 127); 816 817 switch (clk_id) { 818 case CLK_I2C1: 819 rk_clrsetreg(&cru->clksel_con[5], CLK_I2C1_DIV_MASK, 820 (src_clk_div - 1) << CLK_I2C1_DIV_SHIFT); 821 break; 822 case CLK_I2C3: 823 rk_clrsetreg(&cru->clksel_con[5], CLK_I2C3_DIV_MASK, 824 (src_clk_div - 1) << CLK_I2C3_DIV_SHIFT); 825 break; 826 case CLK_I2C4: 827 rk_clrsetreg(&cru->clksel_con[6], CLK_I2C4_DIV_MASK, 828 (src_clk_div - 1) << CLK_I2C4_DIV_SHIFT); 829 break; 830 case CLK_I2C5: 831 rk_clrsetreg(&cru->clksel_con[6], CLK_I2C5_DIV_MASK, 832 (src_clk_div - 1) << CLK_I2C5_DIV_SHIFT); 833 break; 834 default: 835 return -ENOENT; 836 } 837 838 return rv1126_i2c_get_clk(priv, clk_id); 839 } 840 841 static ulong rv1126_spi_get_clk(struct rv1126_clk_priv *priv) 842 { 843 struct rv1126_cru *cru = priv->cru; 844 u32 div, con; 845 846 con = readl(&cru->clksel_con[8]); 847 div = (con & CLK_SPI1_DIV_MASK) >> CLK_SPI1_DIV_SHIFT; 848 849 return DIV_TO_RATE(priv->gpll_hz, div); 850 } 851 852 static ulong rv1126_spi_set_clk(struct rv1126_clk_priv *priv, ulong rate) 853 { 854 struct rv1126_cru *cru = priv->cru; 855 int src_clk_div; 856 857 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); 858 assert(src_clk_div - 1 <= 127); 859 860 rk_clrsetreg(&cru->clksel_con[8], 861 CLK_SPI1_SEL_MASK | CLK_SPI1_DIV_MASK, 862 CLK_SPI1_SEL_GPLL << CLK_SPI1_SEL_SHIFT | 863 (src_clk_div - 1) << CLK_SPI1_DIV_SHIFT); 864 865 return rv1126_spi_get_clk(priv); 866 } 867 868 static ulong rv1126_pwm_get_clk(struct rv1126_clk_priv *priv) 869 { 870 struct rv1126_cru *cru = priv->cru; 871 u32 div, sel, con; 872 873 con = readl(&cru->clksel_con[9]); 874 sel = (con & CLK_PWM2_SEL_MASK) >> CLK_PWM2_SEL_SHIFT; 875 div = (con & CLK_PWM2_DIV_MASK) >> CLK_PWM2_DIV_SHIFT; 876 if (sel == CLK_PWM2_SEL_XIN24M) 877 return OSC_HZ; 878 879 return DIV_TO_RATE(priv->gpll_hz, div); 880 } 881 882 static ulong rv1126_pwm_set_clk(struct rv1126_clk_priv *priv, ulong rate) 883 { 884 struct rv1126_cru *cru = priv->cru; 885 int src_clk_div; 886 887 if (rate == OSC_HZ) { 888 rk_clrsetreg(&cru->clksel_con[9], CLK_PWM2_SEL_MASK, 889 CLK_PWM2_SEL_XIN24M << CLK_PWM2_SEL_SHIFT); 890 rk_clrsetreg(&cru->clksel_con[9], CLK_PWM2_DIV_MASK, 0); 891 } else { 892 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); 893 assert(src_clk_div - 1 <= 127); 894 rk_clrsetreg(&cru->clksel_con[9], CLK_PWM2_DIV_MASK, 895 (src_clk_div - 1) << CLK_PWM2_DIV_SHIFT); 896 rk_clrsetreg(&cru->clksel_con[9], CLK_PWM2_SEL_MASK, 897 CLK_PWM2_SEL_GPLL << CLK_PWM2_SEL_SHIFT); 898 } 899 900 return rv1126_pwm_get_clk(priv); 901 } 902 903 static ulong rv1126_saradc_get_clk(struct rv1126_clk_priv *priv) 904 { 905 struct rv1126_cru *cru = priv->cru; 906 u32 div, con; 907 908 con = readl(&cru->clksel_con[20]); 909 div = (con & CLK_SARADC_DIV_MASK) >> CLK_SARADC_DIV_SHIFT; 910 911 return DIV_TO_RATE(OSC_HZ, div); 912 } 913 914 static ulong rv1126_saradc_set_clk(struct rv1126_clk_priv *priv, ulong rate) 915 { 916 struct rv1126_cru *cru = priv->cru; 917 int src_clk_div; 918 919 src_clk_div = DIV_ROUND_UP(OSC_HZ, rate); 920 assert(src_clk_div - 1 <= 2047); 921 rk_clrsetreg(&cru->clksel_con[20], CLK_SARADC_DIV_MASK, 922 (src_clk_div - 1) << CLK_SARADC_DIV_SHIFT); 923 924 return rv1126_saradc_get_clk(priv); 925 } 926 927 static ulong rv1126_crypto_get_clk(struct rv1126_clk_priv *priv, ulong clk_id) 928 { 929 struct rv1126_cru *cru = priv->cru; 930 u32 div, sel, con, parent; 931 932 switch (clk_id) { 933 case CLK_CRYPTO_CORE: 934 con = readl(&cru->clksel_con[7]); 935 div = (con & CLK_CRYPTO_CORE_DIV_MASK) >> CLK_CRYPTO_CORE_DIV_SHIFT; 936 sel = (con & CLK_CRYPTO_CORE_SEL_MASK) >> CLK_CRYPTO_CORE_SEL_SHIFT; 937 if (sel == CLK_CRYPTO_CORE_SEL_GPLL) 938 parent = priv->gpll_hz; 939 else if (sel == CLK_CRYPTO_CORE_SEL_CPLL) 940 parent = priv->cpll_hz; 941 else 942 return -ENOENT; 943 break; 944 case CLK_CRYPTO_PKA: 945 con = readl(&cru->clksel_con[7]); 946 div = (con & CLK_CRYPTO_PKA_DIV_MASK) >> CLK_CRYPTO_PKA_DIV_SHIFT; 947 sel = (con & CLK_CRYPTO_PKA_SEL_MASK) >> CLK_CRYPTO_PKA_SEL_SHIFT; 948 if (sel == CLK_CRYPTO_PKA_SEL_GPLL) 949 parent = priv->gpll_hz; 950 else if (sel == CLK_CRYPTO_PKA_SEL_CPLL) 951 parent = priv->cpll_hz; 952 else 953 return -ENOENT; 954 break; 955 case ACLK_CRYPTO: 956 con = readl(&cru->clksel_con[4]); 957 div = (con & ACLK_CRYPTO_DIV_MASK) >> ACLK_CRYPTO_DIV_SHIFT; 958 sel = (con & ACLK_CRYPTO_SEL_MASK) >> ACLK_CRYPTO_SEL_SHIFT; 959 if (sel == ACLK_CRYPTO_SEL_GPLL) 960 parent = priv->gpll_hz; 961 else if (sel == ACLK_CRYPTO_SEL_CPLL) 962 parent = priv->cpll_hz; 963 else 964 return -ENOENT; 965 break; 966 default: 967 return -ENOENT; 968 } 969 970 return DIV_TO_RATE(parent, div); 971 } 972 973 static ulong rv1126_crypto_set_clk(struct rv1126_clk_priv *priv, ulong clk_id, 974 ulong rate) 975 { 976 struct rv1126_cru *cru = priv->cru; 977 int src_clk_div; 978 979 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); 980 assert(src_clk_div - 1 <= 31); 981 982 switch (clk_id) { 983 case CLK_CRYPTO_CORE: 984 rk_clrsetreg(&cru->clksel_con[7], 985 CLK_CRYPTO_CORE_SEL_MASK | 986 CLK_CRYPTO_CORE_DIV_MASK, 987 CLK_CRYPTO_CORE_SEL_GPLL << 988 CLK_CRYPTO_CORE_SEL_SHIFT | 989 (src_clk_div - 1) << CLK_CRYPTO_CORE_DIV_SHIFT); 990 break; 991 case CLK_CRYPTO_PKA: 992 rk_clrsetreg(&cru->clksel_con[7], 993 CLK_CRYPTO_PKA_SEL_MASK | 994 CLK_CRYPTO_PKA_DIV_MASK, 995 CLK_CRYPTO_PKA_SEL_GPLL << 996 CLK_CRYPTO_PKA_SEL_SHIFT | 997 (src_clk_div - 1) << CLK_CRYPTO_PKA_DIV_SHIFT); 998 break; 999 case ACLK_CRYPTO: 1000 rk_clrsetreg(&cru->clksel_con[4], 1001 ACLK_CRYPTO_SEL_MASK | ACLK_CRYPTO_DIV_MASK, 1002 ACLK_CRYPTO_SEL_GPLL << ACLK_CRYPTO_SEL_SHIFT | 1003 (src_clk_div - 1) << ACLK_CRYPTO_DIV_SHIFT); 1004 break; 1005 default: 1006 return -ENOENT; 1007 } 1008 1009 return rv1126_crypto_get_clk(priv, clk_id); 1010 } 1011 1012 static ulong rv1126_mmc_get_clk(struct rv1126_clk_priv *priv, ulong clk_id) 1013 { 1014 struct rv1126_cru *cru = priv->cru; 1015 u32 div, sel, con, con_id; 1016 1017 switch (clk_id) { 1018 case HCLK_SDMMC: 1019 case CLK_SDMMC: 1020 con_id = 55; 1021 break; 1022 case HCLK_SDIO: 1023 case CLK_SDIO: 1024 con_id = 56; 1025 break; 1026 case HCLK_EMMC: 1027 case CLK_EMMC: 1028 case SCLK_EMMC_SAMPLE: 1029 con_id = 57; 1030 break; 1031 default: 1032 return -ENOENT; 1033 } 1034 1035 con = readl(&cru->clksel_con[con_id]); 1036 div = (con & EMMC_DIV_MASK) >> EMMC_DIV_SHIFT; 1037 sel = (con & EMMC_SEL_MASK) >> EMMC_SEL_SHIFT; 1038 if (sel == EMMC_SEL_GPLL) 1039 return DIV_TO_RATE(priv->gpll_hz, div) / 2; 1040 else if (sel == EMMC_SEL_CPLL) 1041 return DIV_TO_RATE(priv->cpll_hz, div) / 2; 1042 else if (sel == EMMC_SEL_XIN24M) 1043 return DIV_TO_RATE(OSC_HZ, div) / 2; 1044 1045 return -ENOENT; 1046 } 1047 1048 static ulong rv1126_mmc_set_clk(struct rv1126_clk_priv *priv, ulong clk_id, 1049 ulong rate) 1050 { 1051 struct rv1126_cru *cru = priv->cru; 1052 int src_clk_div; 1053 u32 con_id; 1054 1055 switch (clk_id) { 1056 case HCLK_SDMMC: 1057 case CLK_SDMMC: 1058 con_id = 55; 1059 break; 1060 case HCLK_SDIO: 1061 case CLK_SDIO: 1062 con_id = 56; 1063 break; 1064 case HCLK_EMMC: 1065 case CLK_EMMC: 1066 con_id = 57; 1067 break; 1068 default: 1069 return -ENOENT; 1070 } 1071 1072 /* Select clk_sdmmc/emmc source from GPLL by default */ 1073 /* mmc clock defaulg div 2 internal, need provide double in cru */ 1074 src_clk_div = DIV_ROUND_UP(priv->gpll_hz / 2, rate); 1075 1076 if (src_clk_div > 127) { 1077 /* use 24MHz source for 400KHz clock */ 1078 src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, rate); 1079 rk_clrsetreg(&cru->clksel_con[con_id], 1080 EMMC_SEL_MASK | EMMC_DIV_MASK, 1081 EMMC_SEL_XIN24M << EMMC_SEL_SHIFT | 1082 (src_clk_div - 1) << EMMC_DIV_SHIFT); 1083 } else { 1084 rk_clrsetreg(&cru->clksel_con[con_id], 1085 EMMC_SEL_MASK | EMMC_DIV_MASK, 1086 EMMC_SEL_GPLL << EMMC_SEL_SHIFT | 1087 (src_clk_div - 1) << EMMC_DIV_SHIFT); 1088 } 1089 1090 return rv1126_mmc_get_clk(priv, clk_id); 1091 } 1092 1093 static ulong rv1126_sfc_get_clk(struct rv1126_clk_priv *priv) 1094 { 1095 struct rv1126_cru *cru = priv->cru; 1096 u32 div, sel, con, parent; 1097 1098 con = readl(&cru->clksel_con[58]); 1099 div = (con & SCLK_SFC_DIV_MASK) >> SCLK_SFC_DIV_SHIFT; 1100 sel = (con & SCLK_SFC_SEL_MASK) >> SCLK_SFC_SEL_SHIFT; 1101 if (sel == SCLK_SFC_SEL_GPLL) 1102 parent = priv->gpll_hz; 1103 else if (sel == SCLK_SFC_SEL_CPLL) 1104 parent = priv->cpll_hz; 1105 else 1106 return -ENOENT; 1107 1108 return DIV_TO_RATE(parent, div); 1109 } 1110 1111 static ulong rv1126_sfc_set_clk(struct rv1126_clk_priv *priv, ulong rate) 1112 { 1113 struct rv1126_cru *cru = priv->cru; 1114 int src_clk_div; 1115 1116 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); 1117 rk_clrsetreg(&cru->clksel_con[58], 1118 SCLK_SFC_SEL_MASK | SCLK_SFC_DIV_MASK, 1119 SCLK_SFC_SEL_GPLL << SCLK_SFC_SEL_SHIFT | 1120 (src_clk_div - 1) << SCLK_SFC_DIV_SHIFT); 1121 1122 return rv1126_sfc_get_clk(priv); 1123 } 1124 1125 static ulong rv1126_nand_get_clk(struct rv1126_clk_priv *priv) 1126 { 1127 struct rv1126_cru *cru = priv->cru; 1128 u32 div, sel, con, parent; 1129 1130 con = readl(&cru->clksel_con[59]); 1131 div = (con & CLK_NANDC_DIV_MASK) >> CLK_NANDC_DIV_SHIFT; 1132 sel = (con & CLK_NANDC_SEL_MASK) >> CLK_NANDC_SEL_SHIFT; 1133 if (sel == CLK_NANDC_SEL_GPLL) 1134 parent = priv->gpll_hz; 1135 else if (sel == CLK_NANDC_SEL_CPLL) 1136 parent = priv->cpll_hz; 1137 else 1138 return -ENOENT; 1139 1140 return DIV_TO_RATE(parent, div); 1141 } 1142 1143 static ulong rv1126_nand_set_clk(struct rv1126_clk_priv *priv, ulong rate) 1144 { 1145 struct rv1126_cru *cru = priv->cru; 1146 int src_clk_div; 1147 1148 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); 1149 rk_clrsetreg(&cru->clksel_con[59], 1150 CLK_NANDC_SEL_MASK | CLK_NANDC_DIV_MASK, 1151 CLK_NANDC_SEL_GPLL << CLK_NANDC_SEL_SHIFT | 1152 (src_clk_div - 1) << CLK_NANDC_DIV_SHIFT); 1153 1154 return rv1126_nand_get_clk(priv); 1155 } 1156 1157 static ulong rv1126_aclk_vop_get_clk(struct rv1126_clk_priv *priv) 1158 { 1159 struct rv1126_cru *cru = priv->cru; 1160 u32 div, sel, con, parent; 1161 1162 con = readl(&cru->clksel_con[45]); 1163 div = (con & ACLK_PDVO_DIV_MASK) >> ACLK_PDVO_DIV_SHIFT; 1164 sel = (con & ACLK_PDVO_SEL_MASK) >> ACLK_PDVO_SEL_SHIFT; 1165 if (sel == ACLK_PDVO_SEL_GPLL) 1166 parent = priv->gpll_hz; 1167 else if (sel == ACLK_PDVO_SEL_CPLL) 1168 parent = priv->cpll_hz; 1169 else 1170 return -ENOENT; 1171 1172 return DIV_TO_RATE(parent, div); 1173 } 1174 1175 static ulong rv1126_aclk_vop_set_clk(struct rv1126_clk_priv *priv, ulong rate) 1176 { 1177 struct rv1126_cru *cru = priv->cru; 1178 int src_clk_div; 1179 1180 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); 1181 assert(src_clk_div - 1 <= 31); 1182 rk_clrsetreg(&cru->clksel_con[45], 1183 ACLK_PDVO_SEL_MASK | ACLK_PDVO_DIV_MASK, 1184 ACLK_PDVO_SEL_GPLL << ACLK_PDVO_SEL_SHIFT | 1185 (src_clk_div - 1) << ACLK_PDVO_DIV_SHIFT); 1186 1187 return rv1126_aclk_vop_get_clk(priv); 1188 } 1189 1190 static ulong rv1126_dclk_vop_get_clk(struct rv1126_clk_priv *priv) 1191 { 1192 struct rv1126_cru *cru = priv->cru; 1193 u32 div, sel, con, parent; 1194 1195 con = readl(&cru->clksel_con[47]); 1196 div = (con & DCLK_VOP_DIV_MASK) >> DCLK_VOP_DIV_SHIFT; 1197 sel = (con & DCLK_VOP_SEL_MASK) >> DCLK_VOP_SEL_SHIFT; 1198 if (sel == DCLK_VOP_SEL_GPLL) 1199 parent = priv->gpll_hz; 1200 else if (sel == DCLK_VOP_SEL_CPLL) 1201 parent = priv->cpll_hz; 1202 else 1203 return -ENOENT; 1204 1205 return DIV_TO_RATE(parent, div); 1206 } 1207 1208 static ulong rv1126_dclk_vop_set_clk(struct rv1126_clk_priv *priv, ulong rate) 1209 { 1210 struct rv1126_cru *cru = priv->cru; 1211 ulong pll_rate, now, best_rate = 0; 1212 u32 i, div, best_div = 0, best_sel = 0; 1213 1214 for (i = 0; i <= DCLK_VOP_SEL_CPLL; i++) { 1215 switch (i) { 1216 case DCLK_VOP_SEL_GPLL: 1217 pll_rate = priv->gpll_hz; 1218 break; 1219 case DCLK_VOP_SEL_CPLL: 1220 pll_rate = priv->cpll_hz; 1221 break; 1222 default: 1223 printf("do not support this vop pll sel\n"); 1224 return -EINVAL; 1225 } 1226 1227 div = DIV_ROUND_UP(pll_rate, rate); 1228 if (div > 255) 1229 continue; 1230 now = pll_rate / div; 1231 if (abs(rate - now) < abs(rate - best_rate)) { 1232 best_rate = now; 1233 best_div = div; 1234 best_sel = i; 1235 } 1236 debug("pll_rate=%lu, best_rate=%lu, best_div=%u, best_sel=%u\n", 1237 pll_rate, best_rate, best_div, best_sel); 1238 } 1239 1240 if (best_rate) { 1241 rk_clrsetreg(&cru->clksel_con[47], 1242 DCLK_VOP_SEL_MASK | DCLK_VOP_DIV_MASK, 1243 best_sel << DCLK_VOP_SEL_SHIFT | 1244 (best_div - 1) << DCLK_VOP_DIV_SHIFT); 1245 } else { 1246 printf("do not support this vop freq %lu\n", rate); 1247 return -EINVAL; 1248 } 1249 1250 1251 return rv1126_dclk_vop_get_clk(priv); 1252 } 1253 1254 static ulong rv1126_scr1_get_clk(struct rv1126_clk_priv *priv) 1255 { 1256 struct rv1126_cru *cru = priv->cru; 1257 u32 div, sel, con, parent; 1258 1259 con = readl(&cru->clksel_con[3]); 1260 div = (con & CLK_SCR1_DIV_MASK) >> CLK_SCR1_DIV_SHIFT; 1261 sel = (con & CLK_SCR1_SEL_MASK) >> CLK_SCR1_SEL_SHIFT; 1262 if (sel == CLK_SCR1_SEL_GPLL) 1263 parent = priv->gpll_hz; 1264 else if (sel == CLK_SCR1_SEL_CPLL) 1265 parent = priv->cpll_hz; 1266 else 1267 return -ENOENT; 1268 1269 return DIV_TO_RATE(parent, div); 1270 } 1271 1272 static ulong rv1126_scr1_set_clk(struct rv1126_clk_priv *priv, ulong rate) 1273 { 1274 struct rv1126_cru *cru = priv->cru; 1275 int src_clk_div; 1276 1277 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); 1278 assert(src_clk_div - 1 <= 31); 1279 rk_clrsetreg(&cru->clksel_con[3], 1280 CLK_SCR1_SEL_MASK | CLK_SCR1_DIV_MASK, 1281 CLK_SCR1_SEL_GPLL << CLK_SCR1_SEL_SHIFT | 1282 (src_clk_div - 1) << CLK_SCR1_DIV_SHIFT); 1283 1284 return rv1126_scr1_get_clk(priv); 1285 } 1286 1287 static ulong rv1126_clk_get_rate(struct clk *clk) 1288 { 1289 struct rv1126_clk_priv *priv = dev_get_priv(clk->dev); 1290 ulong rate = 0; 1291 1292 if (!priv->gpll_hz) { 1293 printf("%s gpll=%lu\n", __func__, priv->gpll_hz); 1294 return -ENOENT; 1295 } 1296 1297 switch (clk->id) { 1298 case PLL_APLL: 1299 case ARMCLK: 1300 rate = rockchip_pll_get_rate(&rv1126_pll_clks[APLL], priv->cru, 1301 APLL); 1302 break; 1303 case PLL_CPLL: 1304 rate = rockchip_pll_get_rate(&rv1126_pll_clks[CPLL], priv->cru, 1305 CPLL); 1306 break; 1307 case HCLK_PDCORE_NIU: 1308 rate = rv1126_pdcore_get_clk(priv); 1309 break; 1310 case ACLK_PDBUS: 1311 case HCLK_PDBUS: 1312 case PCLK_PDBUS: 1313 rate = rv1126_pdbus_get_clk(priv, clk->id); 1314 break; 1315 case ACLK_PDPHP: 1316 case HCLK_PDPHP: 1317 rate = rv1126_pdphp_get_clk(priv, clk->id); 1318 break; 1319 case HCLK_PDAUDIO: 1320 rate = rv1126_pdaudio_get_clk(priv); 1321 break; 1322 case CLK_I2C1: 1323 case CLK_I2C3: 1324 case CLK_I2C4: 1325 case CLK_I2C5: 1326 rate = rv1126_i2c_get_clk(priv, clk->id); 1327 break; 1328 case CLK_SPI1: 1329 rate = rv1126_spi_get_clk(priv); 1330 break; 1331 case CLK_PWM2: 1332 rate = rv1126_pwm_get_clk(priv); 1333 break; 1334 case CLK_SARADC: 1335 rate = rv1126_saradc_get_clk(priv); 1336 break; 1337 case CLK_CRYPTO_CORE: 1338 case CLK_CRYPTO_PKA: 1339 case ACLK_CRYPTO: 1340 rate = rv1126_crypto_get_clk(priv, clk->id); 1341 break; 1342 case CLK_SDMMC: 1343 case HCLK_SDMMC: 1344 case CLK_SDIO: 1345 case HCLK_SDIO: 1346 case CLK_EMMC: 1347 case HCLK_EMMC: 1348 case SCLK_EMMC_SAMPLE: 1349 rate = rv1126_mmc_get_clk(priv, clk->id); 1350 break; 1351 case SCLK_SFC: 1352 rate = rv1126_sfc_get_clk(priv); 1353 break; 1354 case CLK_NANDC: 1355 rate = rv1126_nand_get_clk(priv); 1356 break; 1357 case ACLK_PDVO: 1358 case ACLK_VOP: 1359 rate = rv1126_aclk_vop_get_clk(priv); 1360 break; 1361 case DCLK_VOP: 1362 rate = rv1126_dclk_vop_get_clk(priv); 1363 break; 1364 case CLK_SCR1_CORE: 1365 rate = rv1126_scr1_get_clk(priv); 1366 default: 1367 return -ENOENT; 1368 } 1369 1370 return rate; 1371 }; 1372 1373 static ulong rv1126_clk_set_rate(struct clk *clk, ulong rate) 1374 { 1375 struct rv1126_clk_priv *priv = dev_get_priv(clk->dev); 1376 ulong ret = 0; 1377 1378 if (!priv->gpll_hz) { 1379 printf("%s gpll=%lu\n", __func__, priv->gpll_hz); 1380 return -ENOENT; 1381 } 1382 1383 switch (clk->id) { 1384 case PLL_APLL: 1385 case ARMCLK: 1386 if (priv->armclk_hz) 1387 rv1126_armclk_set_clk(priv, rate); 1388 priv->armclk_hz = rate; 1389 break; 1390 case PLL_CPLL: 1391 ret = rockchip_pll_set_rate(&rv1126_pll_clks[CPLL], priv->cru, 1392 CPLL, rate); 1393 break; 1394 case ACLK_PDBUS: 1395 case HCLK_PDBUS: 1396 case PCLK_PDBUS: 1397 ret = rv1126_pdbus_set_clk(priv, clk->id, rate); 1398 break; 1399 case ACLK_PDPHP: 1400 case HCLK_PDPHP: 1401 ret = rv1126_pdphp_set_clk(priv, clk->id, rate); 1402 break; 1403 case HCLK_PDCORE_NIU: 1404 ret = rv1126_pdcore_set_clk(priv, rate); 1405 break; 1406 case HCLK_PDAUDIO: 1407 ret = rv1126_pdaudio_set_clk(priv, rate); 1408 break; 1409 case CLK_I2C1: 1410 case CLK_I2C3: 1411 case CLK_I2C4: 1412 case CLK_I2C5: 1413 ret = rv1126_i2c_set_clk(priv, clk->id, rate); 1414 break; 1415 case CLK_SPI1: 1416 ret = rv1126_spi_set_clk(priv, rate); 1417 break; 1418 case CLK_PWM2: 1419 ret = rv1126_pwm_set_clk(priv, rate); 1420 break; 1421 case CLK_SARADC: 1422 ret = rv1126_saradc_set_clk(priv, rate); 1423 break; 1424 case CLK_CRYPTO_CORE: 1425 case CLK_CRYPTO_PKA: 1426 case ACLK_CRYPTO: 1427 ret = rv1126_crypto_set_clk(priv, clk->id, rate); 1428 break; 1429 case CLK_SDMMC: 1430 case HCLK_SDMMC: 1431 case CLK_SDIO: 1432 case HCLK_SDIO: 1433 case CLK_EMMC: 1434 case HCLK_EMMC: 1435 ret = rv1126_mmc_set_clk(priv, clk->id, rate); 1436 break; 1437 case SCLK_SFC: 1438 ret = rv1126_sfc_set_clk(priv, rate); 1439 break; 1440 case CLK_NANDC: 1441 ret = rv1126_nand_set_clk(priv, rate); 1442 break; 1443 case ACLK_PDVO: 1444 case ACLK_VOP: 1445 ret = rv1126_aclk_vop_set_clk(priv, rate); 1446 break; 1447 case DCLK_VOP: 1448 ret = rv1126_dclk_vop_set_clk(priv, rate); 1449 break; 1450 case CLK_SCR1_CORE: 1451 ret = rv1126_scr1_set_clk(priv, rate); 1452 default: 1453 return -ENOENT; 1454 } 1455 1456 return ret; 1457 }; 1458 1459 #define ROCKCHIP_MMC_DELAY_SEL BIT(10) 1460 #define ROCKCHIP_MMC_DEGREE_MASK 0x3 1461 #define ROCKCHIP_MMC_DELAYNUM_OFFSET 2 1462 #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET) 1463 1464 #define PSECS_PER_SEC 1000000000000LL 1465 /* 1466 * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to 1467 * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg. 1468 */ 1469 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60 1470 1471 int rv1126_mmc_get_phase(struct clk *clk) 1472 { 1473 struct rv1126_clk_priv *priv = dev_get_priv(clk->dev); 1474 struct rv1126_cru *cru = priv->cru; 1475 u32 raw_value, delay_num; 1476 u16 degrees = 0; 1477 ulong rate; 1478 1479 rate = rv1126_clk_get_rate(clk); 1480 if (rate < 0) 1481 return rate; 1482 1483 if (clk->id == SCLK_EMMC_SAMPLE) 1484 raw_value = readl(&cru->emmc_con[1]); 1485 else if (clk->id == SCLK_SDMMC_SAMPLE) 1486 raw_value = readl(&cru->sdmmc_con[1]); 1487 else 1488 raw_value = readl(&cru->sdio_con[1]); 1489 1490 raw_value >>= 1; 1491 degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90; 1492 1493 if (raw_value & ROCKCHIP_MMC_DELAY_SEL) { 1494 /* degrees/delaynum * 10000 */ 1495 unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) * 1496 36 * (rate / 1000000); 1497 1498 delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK); 1499 delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET; 1500 degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000); 1501 } 1502 1503 return degrees % 360; 1504 } 1505 1506 int rv1126_mmc_set_phase(struct clk *clk, u32 degrees) 1507 { 1508 struct rv1126_clk_priv *priv = dev_get_priv(clk->dev); 1509 struct rv1126_cru *cru = priv->cru; 1510 u8 nineties, remainder, delay_num; 1511 u32 raw_value, delay; 1512 ulong rate; 1513 1514 rate = rv1126_clk_get_rate(clk); 1515 if (rate < 0) 1516 return rate; 1517 1518 nineties = degrees / 90; 1519 remainder = (degrees % 90); 1520 1521 /* 1522 * Convert to delay; do a little extra work to make sure we 1523 * don't overflow 32-bit / 64-bit numbers. 1524 */ 1525 delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */ 1526 delay *= remainder; 1527 delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 * 1528 (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10)); 1529 1530 delay_num = (u8)min_t(u32, delay, 255); 1531 1532 raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0; 1533 raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET; 1534 raw_value |= nineties; 1535 1536 raw_value <<= 1; 1537 if (clk->id == SCLK_EMMC_SAMPLE) 1538 writel(raw_value | 0xffff0000, &cru->emmc_con[1]); 1539 else if (clk->id == SCLK_SDMMC_SAMPLE) 1540 writel(raw_value | 0xffff0000, &cru->sdmmc_con[1]); 1541 else 1542 writel(raw_value | 0xffff0000, &cru->sdio_con[1]); 1543 1544 debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n", 1545 degrees, delay_num, raw_value, rv1126_mmc_get_phase(clk)); 1546 1547 return 0; 1548 } 1549 1550 static int rv1126_clk_get_phase(struct clk *clk) 1551 { 1552 int ret; 1553 1554 debug("%s %ld\n", __func__, clk->id); 1555 switch (clk->id) { 1556 case SCLK_EMMC_SAMPLE: 1557 case SCLK_SDMMC_SAMPLE: 1558 case SCLK_SDIO_SAMPLE: 1559 ret = rv1126_mmc_get_phase(clk); 1560 break; 1561 default: 1562 return -ENOENT; 1563 } 1564 1565 return ret; 1566 } 1567 1568 static int rv1126_clk_set_phase(struct clk *clk, int degrees) 1569 { 1570 int ret; 1571 1572 debug("%s %ld\n", __func__, clk->id); 1573 switch (clk->id) { 1574 case SCLK_EMMC_SAMPLE: 1575 case SCLK_SDMMC_SAMPLE: 1576 case SCLK_SDIO_SAMPLE: 1577 ret = rv1126_mmc_set_phase(clk, degrees); 1578 break; 1579 default: 1580 return -ENOENT; 1581 } 1582 1583 return ret; 1584 } 1585 1586 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) 1587 static int rv1126_gmac_src_set_parent(struct clk *clk, struct clk *parent) 1588 { 1589 struct rv1126_clk_priv *priv = dev_get_priv(clk->dev); 1590 struct rv1126_grf *grf = priv->grf; 1591 1592 if (parent->id == CLK_GMAC_SRC_M0) 1593 rk_clrsetreg(&grf->iofunc_con1, GMAC_SRC_SEL_MASK, 1594 GMAC_SRC_SEL_M0 << GMAC_SRC_SEL_SHIFT); 1595 else if(parent->id == CLK_GMAC_SRC_M1) 1596 rk_clrsetreg(&grf->iofunc_con1, GMAC_SRC_SEL_MASK, 1597 GMAC_SRC_SEL_M1 << GMAC_SRC_SEL_SHIFT); 1598 1599 return 0; 1600 } 1601 1602 static int rv1126_gmac_src_m0_set_parent(struct clk *clk, struct clk *parent) 1603 { 1604 struct rv1126_clk_priv *priv = dev_get_priv(clk->dev); 1605 struct rv1126_cru *cru = priv->cru; 1606 1607 if (parent->id == CLK_GMAC_DIV) 1608 rk_clrsetreg(&cru->gmac_con, GMAC_SRC_M0_SEL_MASK, 1609 GMAC_SRC_M0_SEL_INT << GMAC_SRC_M0_SEL_SHIFT); 1610 else 1611 rk_clrsetreg(&cru->gmac_con, GMAC_SRC_SEL_MASK, 1612 GMAC_SRC_M0_SEL_EXT << GMAC_SRC_M0_SEL_SHIFT); 1613 1614 return 0; 1615 } 1616 1617 static int rv1126_gmac_src_m1_set_parent(struct clk *clk, struct clk *parent) 1618 { 1619 struct rv1126_clk_priv *priv = dev_get_priv(clk->dev); 1620 struct rv1126_cru *cru = priv->cru; 1621 1622 if (parent->id == CLK_GMAC_DIV) 1623 rk_clrsetreg(&cru->gmac_con, GMAC_SRC_M0_SEL_MASK, 1624 GMAC_SRC_M1_SEL_INT << GMAC_SRC_M1_SEL_SHIFT); 1625 else 1626 rk_clrsetreg(&cru->gmac_con, GMAC_SRC_SEL_MASK, 1627 GMAC_SRC_M1_SEL_EXT << GMAC_SRC_M1_SEL_SHIFT); 1628 1629 return 0; 1630 } 1631 1632 static int rv1126_clk_set_parent(struct clk *clk, struct clk *parent) 1633 { 1634 switch (clk->id) { 1635 case CLK_GMAC_SRC: 1636 return rv1126_gmac_src_set_parent(clk, parent); 1637 case CLK_GMAC_SRC_M0: 1638 return rv1126_gmac_src_m0_set_parent(clk, parent); 1639 case CLK_GMAC_SRC_M1: 1640 return rv1126_gmac_src_m1_set_parent(clk, parent); 1641 default: 1642 return -ENOENT; 1643 } 1644 1645 return 0; 1646 } 1647 #endif 1648 1649 static struct clk_ops rv1126_clk_ops = { 1650 .get_rate = rv1126_clk_get_rate, 1651 .set_rate = rv1126_clk_set_rate, 1652 .get_phase = rv1126_clk_get_phase, 1653 .set_phase = rv1126_clk_set_phase, 1654 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) 1655 .set_parent = rv1126_clk_set_parent, 1656 #endif 1657 }; 1658 1659 static ulong rv1126_gpll_set_rate(struct rv1126_clk_priv *priv, 1660 struct rv1126_pmuclk_priv *pmu_priv, 1661 ulong rate) 1662 { 1663 ulong emmc_rate, sfc_rate, nandc_rate; 1664 bool restore = false; 1665 1666 if (priv->gpll_hz != OSC_HZ) { 1667 emmc_rate = rv1126_mmc_get_clk(priv, CLK_EMMC); 1668 sfc_rate = rv1126_sfc_get_clk(priv); 1669 nandc_rate = rv1126_nand_get_clk(priv); 1670 debug("%s emmc=%lu, sfc=%lu, nandc=%lu\n", __func__, 1671 emmc_rate, sfc_rate, nandc_rate); 1672 restore = true; 1673 } 1674 1675 /* 1676 * the child div is big enough for gpll 1188MHz, 1677 * even maskrom has change some clocks. 1678 */ 1679 if (rockchip_pll_set_rate(&rv1126_pll_clks[GPLL], 1680 pmu_priv->pmucru, GPLL, rate)) 1681 return -EINVAL; 1682 pmu_priv->gpll_hz = rate; 1683 priv->gpll_hz = rate; 1684 1685 if (restore) { 1686 rv1126_mmc_set_clk(priv, CLK_EMMC, emmc_rate); 1687 rv1126_sfc_set_clk(priv, sfc_rate); 1688 rv1126_nand_set_clk(priv, nandc_rate); 1689 } 1690 1691 return 0; 1692 } 1693 1694 static int rv1126_gpll_set_clk(struct rv1126_clk_priv *priv, ulong rate) 1695 { 1696 struct udevice *pmucru_dev; 1697 struct rv1126_pmuclk_priv *pmu_priv; 1698 int ret; 1699 1700 ret = uclass_get_device_by_driver(UCLASS_CLK, 1701 DM_GET_DRIVER(rockchip_rv1126_pmucru), 1702 &pmucru_dev); 1703 if (ret) { 1704 printf("%s: could not find pmucru device\n", __func__); 1705 return ret; 1706 } 1707 pmu_priv = dev_get_priv(pmucru_dev); 1708 priv->gpll_hz = pmu_priv->gpll_hz; 1709 1710 if (rv1126_gpll_set_rate(priv, pmu_priv, rate)) { 1711 printf("%s: failed to set gpll rate %lu\n", __func__, rate); 1712 return -EINVAL; 1713 } 1714 1715 rv1126_pdpmu_set_pmuclk(pmu_priv, PCLK_PDPMU_HZ); 1716 1717 return 0; 1718 } 1719 1720 static void rv1126_clk_init(struct rv1126_clk_priv *priv) 1721 { 1722 int ret; 1723 1724 priv->sync_kernel = false; 1725 if (!priv->armclk_enter_hz) { 1726 priv->armclk_enter_hz = 1727 rockchip_pll_get_rate(&rv1126_pll_clks[APLL], 1728 priv->cru, APLL); 1729 priv->armclk_init_hz = priv->armclk_enter_hz ; 1730 } 1731 1732 if (priv->armclk_init_hz != APLL_HZ) { 1733 ret = rv1126_armclk_set_clk(priv, APLL_HZ); 1734 if (!ret) 1735 priv->armclk_init_hz = APLL_HZ; 1736 } 1737 if (priv->cpll_hz != CPLL_HZ) { 1738 ret = rockchip_pll_set_rate(&rv1126_pll_clks[CPLL], priv->cru, 1739 CPLL, CPLL_HZ); 1740 if (!ret) 1741 priv->cpll_hz = CPLL_HZ; 1742 } 1743 if (priv->gpll_hz != GPLL_HZ) 1744 rv1126_gpll_set_clk(priv, GPLL_HZ); 1745 1746 rv1126_pdbus_set_clk(priv, ACLK_PDBUS, ACLK_PDBUS_HZ); 1747 rv1126_pdbus_set_clk(priv, HCLK_PDBUS, HCLK_PDBUS_HZ); 1748 rv1126_pdbus_set_clk(priv, PCLK_PDBUS, PCLK_PDBUS_HZ); 1749 rv1126_pdphp_set_clk(priv, ACLK_PDPHP, ACLK_PDPHP_HZ); 1750 rv1126_pdphp_set_clk(priv, HCLK_PDPHP, HCLK_PDPHP_HZ); 1751 rv1126_pdcore_set_clk(priv, HCLK_PDCORE_HZ); 1752 rv1126_pdaudio_set_clk(priv, HCLK_PDAUDIO_HZ); 1753 } 1754 1755 static int rv1126_clk_probe(struct udevice *dev) 1756 { 1757 struct rv1126_clk_priv *priv = dev_get_priv(dev); 1758 int ret; 1759 1760 priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 1761 if (IS_ERR(priv->grf)) 1762 return PTR_ERR(priv->grf); 1763 1764 rv1126_clk_init(priv); 1765 1766 /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */ 1767 ret = clk_set_defaults(dev); 1768 if (ret) 1769 debug("%s clk_set_defaults failed %d\n", __func__, ret); 1770 else 1771 priv->sync_kernel = true; 1772 1773 return 0; 1774 } 1775 1776 static int rv1126_clk_ofdata_to_platdata(struct udevice *dev) 1777 { 1778 struct rv1126_clk_priv *priv = dev_get_priv(dev); 1779 1780 priv->cru = dev_read_addr_ptr(dev); 1781 1782 return 0; 1783 } 1784 1785 static int rv1126_clk_bind(struct udevice *dev) 1786 { 1787 int ret; 1788 struct udevice *sys_child, *sf_child; 1789 struct sysreset_reg *priv; 1790 struct softreset_reg *sf_priv; 1791 1792 /* The reset driver does not have a device node, so bind it here */ 1793 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset", 1794 &sys_child); 1795 if (ret) { 1796 debug("Warning: No sysreset driver: ret=%d\n", ret); 1797 } else { 1798 priv = malloc(sizeof(struct sysreset_reg)); 1799 priv->glb_srst_fst_value = offsetof(struct rv1126_cru, 1800 glb_srst_fst); 1801 priv->glb_srst_snd_value = offsetof(struct rv1126_cru, 1802 glb_srst_snd); 1803 sys_child->priv = priv; 1804 } 1805 1806 ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset", 1807 dev_ofnode(dev), &sf_child); 1808 if (ret) { 1809 debug("Warning: No rockchip reset driver: ret=%d\n", ret); 1810 } else { 1811 sf_priv = malloc(sizeof(struct softreset_reg)); 1812 sf_priv->sf_reset_offset = offsetof(struct rv1126_cru, 1813 softrst_con[0]); 1814 sf_priv->sf_reset_num = 15; 1815 sf_child->priv = sf_priv; 1816 } 1817 1818 return 0; 1819 } 1820 1821 static const struct udevice_id rv1126_clk_ids[] = { 1822 { .compatible = "rockchip,rv1126-cru" }, 1823 { } 1824 }; 1825 1826 U_BOOT_DRIVER(rockchip_rv1126_cru) = { 1827 .name = "rockchip_rv1126_cru", 1828 .id = UCLASS_CLK, 1829 .of_match = rv1126_clk_ids, 1830 .priv_auto_alloc_size = sizeof(struct rv1126_clk_priv), 1831 .ofdata_to_platdata = rv1126_clk_ofdata_to_platdata, 1832 .ops = &rv1126_clk_ops, 1833 .bind = rv1126_clk_bind, 1834 .probe = rv1126_clk_probe, 1835 }; 1836 1837 #ifndef CONFIG_SPL_BUILD 1838 /** 1839 * soc_clk_dump() - Print clock frequencies 1840 * Returns zero on success 1841 * 1842 * Implementation for the clk dump command. 1843 */ 1844 int soc_clk_dump(void) 1845 { 1846 struct udevice *cru_dev, *pmucru_dev; 1847 struct rv1126_clk_priv *priv; 1848 const struct rv1126_clk_info *clk_dump; 1849 struct clk clk; 1850 unsigned long clk_count = ARRAY_SIZE(clks_dump); 1851 unsigned long rate; 1852 int i, ret; 1853 1854 ret = uclass_get_device_by_driver(UCLASS_CLK, 1855 DM_GET_DRIVER(rockchip_rv1126_cru), 1856 &cru_dev); 1857 if (ret) { 1858 printf("%s failed to get cru device\n", __func__); 1859 return ret; 1860 } 1861 1862 ret = uclass_get_device_by_driver(UCLASS_CLK, 1863 DM_GET_DRIVER(rockchip_rv1126_pmucru), 1864 &pmucru_dev); 1865 if (ret) { 1866 printf("%s failed to get pmucru device\n", __func__); 1867 return ret; 1868 } 1869 1870 priv = dev_get_priv(cru_dev); 1871 printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n", 1872 priv->sync_kernel ? "sync kernel" : "uboot", 1873 priv->armclk_enter_hz / 1000, 1874 priv->armclk_init_hz / 1000, 1875 priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0, 1876 priv->set_armclk_rate ? " KHz" : "N/A"); 1877 for (i = 0; i < clk_count; i++) { 1878 clk_dump = &clks_dump[i]; 1879 if (clk_dump->name) { 1880 clk.id = clk_dump->id; 1881 if (clk_dump->is_cru) 1882 ret = clk_request(cru_dev, &clk); 1883 else 1884 ret = clk_request(pmucru_dev, &clk); 1885 if (ret < 0) 1886 return ret; 1887 1888 rate = clk_get_rate(&clk); 1889 clk_free(&clk); 1890 if (i == 0) { 1891 if (rate < 0) 1892 printf(" %s %s\n", clk_dump->name, 1893 "unknown"); 1894 else 1895 printf(" %s %lu KHz\n", clk_dump->name, 1896 rate / 1000); 1897 } else { 1898 if (rate < 0) 1899 printf(" %s %s\n", clk_dump->name, 1900 "unknown"); 1901 else 1902 printf(" %s %lu KHz\n", clk_dump->name, 1903 rate / 1000); 1904 } 1905 } 1906 } 1907 1908 return 0; 1909 } 1910 #endif 1911