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