1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2020 Fuzhou Rockchip Electronics Co., Ltd 4 * Author: Elaine Zhang <zhangqing@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_rk3568.h> 15 #include <asm/arch/hardware.h> 16 #include <asm/io.h> 17 #include <dm/lists.h> 18 #include <dt-bindings/clock/rk3568-cru.h> 19 20 DECLARE_GLOBAL_DATA_PTR; 21 22 #define RK3568_CPUCLK_RATE(_rate, _aclk_div, _pclk_div) \ 23 { \ 24 .rate = _rate##U, \ 25 .aclk_div = _aclk_div, \ 26 .pclk_div = _pclk_div, \ 27 } 28 29 #define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1)) 30 31 static struct rockchip_cpu_rate_table rk3568_cpu_rates[] = { 32 RK3568_CPUCLK_RATE(1416000000, 1, 5), 33 RK3568_CPUCLK_RATE(1296000000, 1, 5), 34 RK3568_CPUCLK_RATE(1200000000, 1, 3), 35 RK3568_CPUCLK_RATE(1104000000, 1, 3), 36 RK3568_CPUCLK_RATE(1008000000, 1, 3), 37 RK3568_CPUCLK_RATE(912000000, 1, 3), 38 RK3568_CPUCLK_RATE(816000000, 1, 3), 39 RK3568_CPUCLK_RATE(600000000, 1, 1), 40 RK3568_CPUCLK_RATE(408000000, 1, 1), 41 { /* sentinel */ }, 42 }; 43 44 static struct rockchip_pll_rate_table rk3568_pll_rates[] = { 45 /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */ 46 RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0), 47 RK3036_PLL_RATE(1416000000, 1, 118, 2, 1, 1, 0), 48 RK3036_PLL_RATE(1296000000, 1, 108, 2, 1, 1, 0), 49 RK3036_PLL_RATE(1200000000, 1, 100, 2, 1, 1, 0), 50 RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0), 51 RK3036_PLL_RATE(1104000000, 1, 92, 2, 1, 1, 0), 52 RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0), 53 RK3036_PLL_RATE(1000000000, 3, 250, 2, 1, 1, 0), 54 RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0), 55 RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0), 56 RK3036_PLL_RATE(600000000, 1, 100, 4, 1, 1, 0), 57 RK3036_PLL_RATE(594000000, 1, 99, 4, 1, 1, 0), 58 RK3036_PLL_RATE(500000000, 1, 125, 6, 1, 1, 0), 59 RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0), 60 RK3036_PLL_RATE(400000000, 1, 100, 6, 1, 1, 0), 61 RK3036_PLL_RATE(200000000, 1, 100, 6, 2, 1, 0), 62 RK3036_PLL_RATE(100000000, 1, 150, 6, 6, 1, 0), 63 { /* sentinel */ }, 64 }; 65 66 static struct rockchip_pll_clock rk3568_pll_clks[] = { 67 [APLL] = PLL(pll_rk3328, PLL_APLL, RK3568_PLL_CON(0), 68 RK3568_MODE_CON, 0, 10, 0, rk3568_pll_rates), 69 [DPLL] = PLL(pll_rk3328, PLL_DPLL, RK3568_PLL_CON(8), 70 RK3568_MODE_CON, 2, 10, 0, NULL), 71 [CPLL] = PLL(pll_rk3328, PLL_CPLL, RK3568_PLL_CON(24), 72 RK3568_MODE_CON, 4, 10, 0, rk3568_pll_rates), 73 [GPLL] = PLL(pll_rk3328, PLL_HPLL, RK3568_PLL_CON(16), 74 RK3568_MODE_CON, 6, 10, 0, rk3568_pll_rates), 75 [NPLL] = PLL(pll_rk3328, PLL_NPLL, RK3568_PLL_CON(32), 76 RK3568_MODE_CON, 10, 10, 0, rk3568_pll_rates), 77 [VPLL] = PLL(pll_rk3328, PLL_VPLL, RK3568_PLL_CON(40), 78 RK3568_MODE_CON, 12, 10, 0, rk3568_pll_rates), 79 [PPLL] = PLL(pll_rk3328, PLL_PPLL, RK3568_PMU_PLL_CON(0), 80 RK3568_PMU_MODE, 0, 10, 0, rk3568_pll_rates), 81 [HPLL] = PLL(pll_rk3328, PLL_HPLL, RK3568_PMU_PLL_CON(16), 82 RK3568_PMU_MODE, 2, 10, 0, rk3568_pll_rates), 83 }; 84 85 #ifndef CONFIG_SPL_BUILD 86 #define RK3568_CLK_DUMP(_id, _name, _iscru) \ 87 { \ 88 .id = _id, \ 89 .name = _name, \ 90 .is_cru = _iscru, \ 91 } 92 93 static const struct rk3568_clk_info clks_dump[] = { 94 RK3568_CLK_DUMP(PLL_APLL, "apll", true), 95 RK3568_CLK_DUMP(PLL_DPLL, "dpll", true), 96 RK3568_CLK_DUMP(PLL_GPLL, "gpll", true), 97 RK3568_CLK_DUMP(PLL_CPLL, "cpll", true), 98 RK3568_CLK_DUMP(PLL_NPLL, "npll", true), 99 RK3568_CLK_DUMP(PLL_VPLL, "vpll", true), 100 RK3568_CLK_DUMP(PLL_HPLL, "hpll", false), 101 RK3568_CLK_DUMP(PLL_PPLL, "ppll", false), 102 RK3568_CLK_DUMP(ARMCLK, "armclk", true), 103 RK3568_CLK_DUMP(ACLK_BUS, "aclk_bus", true), 104 RK3568_CLK_DUMP(PCLK_BUS, "pclk_bus", true), 105 RK3568_CLK_DUMP(ACLK_TOP_HIGH, "aclk_top_high", true), 106 RK3568_CLK_DUMP(ACLK_TOP_LOW, "aclk_top_low", true), 107 RK3568_CLK_DUMP(HCLK_TOP, "hclk_top", true), 108 RK3568_CLK_DUMP(PCLK_TOP, "pclk_top", true), 109 RK3568_CLK_DUMP(ACLK_PERIMID, "aclk_perimid", true), 110 RK3568_CLK_DUMP(HCLK_PERIMID, "hclk_perimid", true), 111 RK3568_CLK_DUMP(PCLK_PMU, "pclk_pmu", false), 112 }; 113 #endif 114 115 static ulong __maybe_unused 116 rk3568_pmu_pll_set_rate(struct rk3568_clk_priv *priv, 117 ulong pll_id, ulong rate) 118 { 119 struct udevice *pmucru_dev; 120 struct rk3568_pmuclk_priv *pmu_priv; 121 int ret; 122 123 ret = uclass_get_device_by_driver(UCLASS_CLK, 124 DM_GET_DRIVER(rockchip_rk3568_pmucru), 125 &pmucru_dev); 126 if (ret) { 127 printf("%s: could not find pmucru device\n", __func__); 128 return ret; 129 } 130 pmu_priv = dev_get_priv(pmucru_dev); 131 132 rockchip_pll_set_rate(&rk3568_pll_clks[pll_id], 133 pmu_priv->pmucru, pll_id, rate); 134 135 return 0; 136 } 137 138 static ulong rk3568_pmu_pll_get_rate(struct rk3568_clk_priv *priv, 139 ulong pll_id) 140 { 141 struct udevice *pmucru_dev; 142 struct rk3568_pmuclk_priv *pmu_priv; 143 int ret; 144 145 ret = uclass_get_device_by_driver(UCLASS_CLK, 146 DM_GET_DRIVER(rockchip_rk3568_pmucru), 147 &pmucru_dev); 148 if (ret) { 149 printf("%s: could not find pmucru device\n", __func__); 150 return ret; 151 } 152 pmu_priv = dev_get_priv(pmucru_dev); 153 154 return rockchip_pll_get_rate(&rk3568_pll_clks[pll_id], 155 pmu_priv->pmucru, pll_id); 156 } 157 158 /* 159 * 160 * rational_best_approximation(31415, 10000, 161 * (1 << 8) - 1, (1 << 5) - 1, &n, &d); 162 * 163 * you may look at given_numerator as a fixed point number, 164 * with the fractional part size described in given_denominator. 165 * 166 * for theoretical background, see: 167 * http://en.wikipedia.org/wiki/Continued_fraction 168 */ 169 static void rational_best_approximation(unsigned long given_numerator, 170 unsigned long given_denominator, 171 unsigned long max_numerator, 172 unsigned long max_denominator, 173 unsigned long *best_numerator, 174 unsigned long *best_denominator) 175 { 176 unsigned long n, d, n0, d0, n1, d1; 177 178 n = given_numerator; 179 d = given_denominator; 180 n0 = 0; 181 d1 = 0; 182 n1 = 1; 183 d0 = 1; 184 for (;;) { 185 unsigned long t, a; 186 187 if (n1 > max_numerator || d1 > max_denominator) { 188 n1 = n0; 189 d1 = d0; 190 break; 191 } 192 if (d == 0) 193 break; 194 t = d; 195 a = n / d; 196 d = n % d; 197 n = t; 198 t = n0 + a * n1; 199 n0 = n1; 200 n1 = t; 201 t = d0 + a * d1; 202 d0 = d1; 203 d1 = t; 204 } 205 *best_numerator = n1; 206 *best_denominator = d1; 207 } 208 209 static ulong rk3568_rtc32k_get_pmuclk(struct rk3568_pmuclk_priv *priv) 210 { 211 struct rk3568_pmucru *pmucru = priv->pmucru; 212 unsigned long m, n; 213 u32 fracdiv; 214 215 fracdiv = readl(&pmucru->pmu_clksel_con[1]); 216 m = fracdiv & RTC32K_FRAC_NUMERATOR_MASK; 217 m >>= RTC32K_FRAC_NUMERATOR_SHIFT; 218 n = fracdiv & RTC32K_FRAC_DENOMINATOR_MASK; 219 n >>= RTC32K_FRAC_DENOMINATOR_SHIFT; 220 221 return OSC_HZ * m / n; 222 } 223 224 static ulong rk3568_rtc32k_set_pmuclk(struct rk3568_pmuclk_priv *priv, 225 ulong rate) 226 { 227 struct rk3568_pmucru *pmucru = priv->pmucru; 228 unsigned long m, n, val; 229 230 rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK, 231 RTC32K_SEL_OSC0_DIV32K << RTC32K_SEL_SHIFT); 232 233 rational_best_approximation(rate, OSC_HZ, 234 GENMASK(16 - 1, 0), 235 GENMASK(16 - 1, 0), 236 &m, &n); 237 val = m << RTC32K_FRAC_NUMERATOR_SHIFT | n; 238 writel(val, &pmucru->pmu_clksel_con[1]); 239 240 return rk3568_rtc32k_get_pmuclk(priv); 241 } 242 243 static ulong rk3568_i2c_get_pmuclk(struct rk3568_pmuclk_priv *priv, 244 ulong clk_id) 245 { 246 struct rk3568_pmucru *pmucru = priv->pmucru; 247 u32 div, con; 248 249 switch (clk_id) { 250 case CLK_I2C0: 251 con = readl(&pmucru->pmu_clksel_con[3]); 252 div = (con & CLK_I2C0_DIV_MASK) >> CLK_I2C0_DIV_SHIFT; 253 break; 254 default: 255 return -ENOENT; 256 } 257 258 return DIV_TO_RATE(priv->ppll_hz, div); 259 } 260 261 static ulong rk3568_i2c_set_pmuclk(struct rk3568_pmuclk_priv *priv, 262 ulong clk_id, ulong rate) 263 { 264 struct rk3568_pmucru *pmucru = priv->pmucru; 265 int src_clk_div; 266 267 src_clk_div = DIV_ROUND_UP(priv->ppll_hz, rate); 268 assert(src_clk_div - 1 <= 127); 269 270 switch (clk_id) { 271 case CLK_I2C0: 272 rk_clrsetreg(&pmucru->pmu_clksel_con[3], CLK_I2C0_DIV_MASK, 273 (src_clk_div - 1) << CLK_I2C0_DIV_SHIFT); 274 break; 275 default: 276 return -ENOENT; 277 } 278 279 return rk3568_i2c_get_pmuclk(priv, clk_id); 280 } 281 282 static ulong rk3568_pwm_get_pmuclk(struct rk3568_pmuclk_priv *priv, 283 ulong clk_id) 284 { 285 struct rk3568_pmucru *pmucru = priv->pmucru; 286 u32 div, sel, con, parent; 287 288 switch (clk_id) { 289 case CLK_PWM0: 290 con = readl(&pmucru->pmu_clksel_con[6]); 291 sel = (con & CLK_PWM0_SEL_MASK) >> CLK_PWM0_SEL_SHIFT; 292 div = (con & CLK_PWM0_DIV_MASK) >> CLK_PWM0_DIV_SHIFT; 293 if (sel == CLK_PWM0_SEL_XIN24M) 294 parent = OSC_HZ; 295 else 296 parent = priv->ppll_hz; 297 break; 298 default: 299 return -ENOENT; 300 } 301 302 return DIV_TO_RATE(parent, div); 303 } 304 305 static ulong rk3568_pwm_set_pmuclk(struct rk3568_pmuclk_priv *priv, 306 ulong clk_id, ulong rate) 307 { 308 struct rk3568_pmucru *pmucru = priv->pmucru; 309 int src_clk_div; 310 311 switch (clk_id) { 312 case CLK_PWM0: 313 if (rate == OSC_HZ) { 314 rk_clrsetreg(&pmucru->pmu_clksel_con[6], 315 CLK_PWM0_SEL_MASK | CLK_PWM0_DIV_MASK, 316 (CLK_PWM0_SEL_XIN24M << 317 CLK_PWM0_SEL_SHIFT) | 318 0 << CLK_PWM0_SEL_SHIFT); 319 } else { 320 src_clk_div = DIV_ROUND_UP(priv->ppll_hz, rate); 321 assert(src_clk_div - 1 <= 127); 322 rk_clrsetreg(&pmucru->pmu_clksel_con[6], 323 CLK_PWM0_DIV_MASK | CLK_PWM0_DIV_MASK, 324 (CLK_PWM0_SEL_PPLL << CLK_PWM0_SEL_SHIFT) | 325 (src_clk_div - 1) << CLK_PWM0_DIV_SHIFT); 326 } 327 break; 328 default: 329 return -ENOENT; 330 } 331 332 return rk3568_pwm_get_pmuclk(priv, clk_id); 333 } 334 335 static ulong rk3568_pmu_get_pmuclk(struct rk3568_pmuclk_priv *priv) 336 { 337 struct rk3568_pmucru *pmucru = priv->pmucru; 338 u32 div, con, sel, parent; 339 340 con = readl(&pmucru->pmu_clksel_con[2]); 341 sel = (con & PCLK_PDPMU_SEL_MASK) >> PCLK_PDPMU_SEL_SHIFT; 342 div = (con & PCLK_PDPMU_DIV_MASK) >> PCLK_PDPMU_DIV_SHIFT; 343 if (sel) 344 parent = GPLL_HZ; 345 else 346 parent = priv->ppll_hz; 347 348 return DIV_TO_RATE(parent, div); 349 } 350 351 static ulong rk3568_pmu_set_pmuclk(struct rk3568_pmuclk_priv *priv, 352 ulong rate) 353 { 354 struct rk3568_pmucru *pmucru = priv->pmucru; 355 int src_clk_div; 356 357 src_clk_div = DIV_ROUND_UP(priv->ppll_hz, rate); 358 assert(src_clk_div - 1 <= 31); 359 360 rk_clrsetreg(&pmucru->pmu_clksel_con[2], 361 PCLK_PDPMU_DIV_MASK | PCLK_PDPMU_SEL_MASK, 362 (PCLK_PDPMU_SEL_PPLL << PCLK_PDPMU_SEL_SHIFT) | 363 ((src_clk_div - 1) << PCLK_PDPMU_DIV_SHIFT)); 364 365 return rk3568_pmu_get_pmuclk(priv); 366 } 367 368 static ulong rk3568_pmuclk_get_rate(struct clk *clk) 369 { 370 struct rk3568_pmuclk_priv *priv = dev_get_priv(clk->dev); 371 ulong rate = 0; 372 373 if (!priv->ppll_hz) { 374 printf("%s ppll=%lu\n", __func__, priv->ppll_hz); 375 return -ENOENT; 376 } 377 378 debug("%s %ld\n", __func__, clk->id); 379 switch (clk->id) { 380 case PLL_PPLL: 381 rate = rockchip_pll_get_rate(&rk3568_pll_clks[PPLL], 382 priv->pmucru, PPLL); 383 break; 384 case PLL_HPLL: 385 rate = rockchip_pll_get_rate(&rk3568_pll_clks[HPLL], 386 priv->pmucru, HPLL); 387 break; 388 case CLK_RTC_32K: 389 case CLK_RTC32K_FRAC: 390 rate = rk3568_rtc32k_get_pmuclk(priv); 391 break; 392 case CLK_I2C0: 393 rate = rk3568_i2c_get_pmuclk(priv, clk->id); 394 break; 395 case CLK_PWM0: 396 rate = rk3568_pwm_get_pmuclk(priv, clk->id); 397 break; 398 case PCLK_PMU: 399 rate = rk3568_pmu_get_pmuclk(priv); 400 break; 401 default: 402 return -ENOENT; 403 } 404 405 return rate; 406 } 407 408 static ulong rk3568_pmuclk_set_rate(struct clk *clk, ulong rate) 409 { 410 struct rk3568_pmuclk_priv *priv = dev_get_priv(clk->dev); 411 ulong ret = 0; 412 413 if (!priv->ppll_hz) { 414 printf("%s ppll=%lu\n", __func__, priv->ppll_hz); 415 return -ENOENT; 416 } 417 418 debug("%s %ld %ld\n", __func__, clk->id, rate); 419 switch (clk->id) { 420 case PLL_PPLL: 421 ret = rockchip_pll_set_rate(&rk3568_pll_clks[PPLL], 422 priv->pmucru, PPLL, rate); 423 priv->ppll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[PPLL], 424 priv->pmucru, PPLL); 425 break; 426 case PLL_HPLL: 427 ret = rockchip_pll_set_rate(&rk3568_pll_clks[HPLL], 428 priv->pmucru, HPLL, rate); 429 priv->hpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[HPLL], 430 priv->pmucru, HPLL); 431 break; 432 case CLK_RTC_32K: 433 case CLK_RTC32K_FRAC: 434 ret = rk3568_rtc32k_set_pmuclk(priv, rate); 435 break; 436 case CLK_I2C0: 437 ret = rk3568_i2c_set_pmuclk(priv, clk->id, rate); 438 break; 439 case CLK_PWM0: 440 ret = rk3568_pwm_set_pmuclk(priv, clk->id, rate); 441 break; 442 case PCLK_PMU: 443 ret = rk3568_pmu_set_pmuclk(priv, rate); 444 break; 445 default: 446 return -ENOENT; 447 } 448 449 return ret; 450 } 451 452 static int rk3568_rtc32k_set_parent(struct clk *clk, struct clk *parent) 453 { 454 struct rk3568_pmuclk_priv *priv = dev_get_priv(clk->dev); 455 struct rk3568_pmucru *pmucru = priv->pmucru; 456 457 if (parent->id == CLK_RTC32K_FRAC) 458 rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK, 459 RTC32K_SEL_OSC0_DIV32K << RTC32K_SEL_SHIFT); 460 else 461 rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK, 462 RTC32K_SEL_OSC1_32K << RTC32K_SEL_SHIFT); 463 464 return 0; 465 } 466 467 static int rk3568_pmuclk_set_parent(struct clk *clk, struct clk *parent) 468 { 469 switch (clk->id) { 470 case CLK_RTC_32K: 471 return rk3568_rtc32k_set_parent(clk, parent); 472 default: 473 return -ENOENT; 474 } 475 } 476 477 static struct clk_ops rk3568_pmuclk_ops = { 478 .get_rate = rk3568_pmuclk_get_rate, 479 .set_rate = rk3568_pmuclk_set_rate, 480 .set_parent = rk3568_pmuclk_set_parent, 481 }; 482 483 static int rk3568_pmuclk_probe(struct udevice *dev) 484 { 485 struct rk3568_pmuclk_priv *priv = dev_get_priv(dev); 486 int ret = 0; 487 488 if (priv->ppll_hz != PPLL_HZ) { 489 ret = rockchip_pll_set_rate(&rk3568_pll_clks[PPLL], 490 priv->pmucru, 491 PPLL, PPLL_HZ); 492 if (!ret) 493 priv->ppll_hz = PPLL_HZ; 494 } 495 496 /* Ungate PCIe30phy refclk_m and refclk_n */ 497 rk_clrsetreg(&priv->pmucru->pmu_clkgate_con[2], 0x3 << 13, 0 << 13); 498 return 0; 499 } 500 501 static int rk3568_pmuclk_ofdata_to_platdata(struct udevice *dev) 502 { 503 struct rk3568_pmuclk_priv *priv = dev_get_priv(dev); 504 505 priv->pmucru = dev_read_addr_ptr(dev); 506 507 return 0; 508 } 509 510 static int rk3568_pmuclk_bind(struct udevice *dev) 511 { 512 int ret = 0; 513 struct udevice *sf_child; 514 struct softreset_reg *sf_priv; 515 516 ret = device_bind_driver_to_node(dev, "rockchip_reset", 517 "reset", dev_ofnode(dev), 518 &sf_child); 519 if (ret) { 520 debug("Warning: No rockchip reset driver: ret=%d\n", ret); 521 } else { 522 sf_priv = malloc(sizeof(struct softreset_reg)); 523 sf_priv->sf_reset_offset = offsetof(struct rk3568_pmucru, 524 pmu_softrst_con[0]); 525 sf_priv->sf_reset_num = 1; 526 sf_child->priv = sf_priv; 527 } 528 529 return 0; 530 } 531 532 static const struct udevice_id rk3568_pmuclk_ids[] = { 533 { .compatible = "rockchip,rk3568-pmucru" }, 534 { } 535 }; 536 537 U_BOOT_DRIVER(rockchip_rk3568_pmucru) = { 538 .name = "rockchip_rk3568_pmucru", 539 .id = UCLASS_CLK, 540 .of_match = rk3568_pmuclk_ids, 541 .priv_auto_alloc_size = sizeof(struct rk3568_pmuclk_priv), 542 .ofdata_to_platdata = rk3568_pmuclk_ofdata_to_platdata, 543 .ops = &rk3568_pmuclk_ops, 544 .bind = rk3568_pmuclk_bind, 545 .probe = rk3568_pmuclk_probe, 546 }; 547 548 static int rk3568_armclk_set_clk(struct rk3568_clk_priv *priv, ulong hz) 549 { 550 struct rk3568_cru *cru = priv->cru; 551 const struct rockchip_cpu_rate_table *rate; 552 ulong old_rate; 553 554 rate = rockchip_get_cpu_settings(rk3568_cpu_rates, hz); 555 if (!rate) { 556 printf("%s unsupported rate\n", __func__); 557 return -EINVAL; 558 } 559 560 rk_clrsetreg(&cru->clksel_con[0], 561 CLK_CORE_PRE_SEL_MASK, 562 (CLK_CORE_PRE_SEL_SRC << CLK_CORE_PRE_SEL_SHIFT)); 563 rk_clrsetreg(&cru->clksel_con[2], 564 SCLK_CORE_PRE_SEL_MASK | 565 SCLK_CORE_SRC_SEL_MASK | 566 SCLK_CORE_SRC_DIV_MASK, 567 (SCLK_CORE_PRE_SEL_SRC << 568 SCLK_CORE_PRE_SEL_SHIFT) | 569 (SCLK_CORE_SRC_SEL_APLL << 570 SCLK_CORE_SRC_SEL_SHIFT) | 571 (1 << SCLK_CORE_SRC_DIV_SHIFT)); 572 573 /* 574 * set up dependent divisors for DBG and ACLK clocks. 575 */ 576 old_rate = rockchip_pll_get_rate(&rk3568_pll_clks[APLL], 577 priv->cru, APLL); 578 if (old_rate > hz) { 579 if (rockchip_pll_set_rate(&rk3568_pll_clks[APLL], 580 priv->cru, APLL, hz)) 581 return -EINVAL; 582 rk_clrsetreg(&cru->clksel_con[3], 583 GICCLK_CORE_DIV_MASK | ATCLK_CORE_DIV_MASK, 584 rate->pclk_div << GICCLK_CORE_DIV_SHIFT | 585 rate->pclk_div << ATCLK_CORE_DIV_SHIFT); 586 rk_clrsetreg(&cru->clksel_con[4], 587 PERIPHCLK_CORE_PRE_DIV_MASK | 588 PCLK_CORE_PRE_DIV_MASK, 589 rate->pclk_div << PCLK_CORE_PRE_DIV_SHIFT | 590 rate->pclk_div << PERIPHCLK_CORE_PRE_DIV_SHIFT); 591 rk_clrsetreg(&cru->clksel_con[5], 592 ACLK_CORE_NDFT_DIV_MASK, 593 rate->aclk_div << ACLK_CORE_NDFT_DIV_SHIFT); 594 } else if (old_rate < hz) { 595 rk_clrsetreg(&cru->clksel_con[3], 596 GICCLK_CORE_DIV_MASK | ATCLK_CORE_DIV_MASK, 597 rate->pclk_div << GICCLK_CORE_DIV_SHIFT | 598 rate->pclk_div << ATCLK_CORE_DIV_SHIFT); 599 rk_clrsetreg(&cru->clksel_con[4], 600 PERIPHCLK_CORE_PRE_DIV_MASK | 601 PCLK_CORE_PRE_DIV_MASK, 602 rate->pclk_div << PCLK_CORE_PRE_DIV_SHIFT | 603 rate->pclk_div << PERIPHCLK_CORE_PRE_DIV_SHIFT); 604 rk_clrsetreg(&cru->clksel_con[5], 605 ACLK_CORE_NDFT_DIV_MASK, 606 rate->aclk_div << ACLK_CORE_NDFT_DIV_SHIFT); 607 if (rockchip_pll_set_rate(&rk3568_pll_clks[APLL], 608 priv->cru, APLL, hz)) 609 return -EINVAL; 610 } 611 612 return 0; 613 } 614 615 static ulong rk3568_cpll_div_get_rate(struct rk3568_clk_priv *priv, 616 ulong clk_id) 617 { 618 struct rk3568_cru *cru = priv->cru; 619 int div, mask, shift, con; 620 621 switch (clk_id) { 622 case CPLL_500M: 623 con = 78; 624 mask = CPLL_500M_DIV_MASK; 625 shift = CPLL_500M_DIV_SHIFT; 626 break; 627 case CPLL_333M: 628 con = 79; 629 mask = CPLL_333M_DIV_MASK; 630 shift = CPLL_333M_DIV_SHIFT; 631 break; 632 case CPLL_250M: 633 con = 79; 634 mask = CPLL_250M_DIV_MASK; 635 shift = CPLL_250M_DIV_SHIFT; 636 break; 637 case CPLL_125M: 638 con = 80; 639 mask = CPLL_125M_DIV_MASK; 640 shift = CPLL_125M_DIV_SHIFT; 641 break; 642 case CPLL_100M: 643 con = 82; 644 mask = CPLL_100M_DIV_MASK; 645 shift = CPLL_100M_DIV_SHIFT; 646 break; 647 case CPLL_62P5M: 648 con = 80; 649 mask = CPLL_62P5M_DIV_MASK; 650 shift = CPLL_62P5M_DIV_SHIFT; 651 break; 652 case CPLL_50M: 653 con = 81; 654 mask = CPLL_50M_DIV_MASK; 655 shift = CPLL_50M_DIV_SHIFT; 656 break; 657 case CPLL_25M: 658 con = 81; 659 mask = CPLL_25M_DIV_MASK; 660 shift = CPLL_25M_DIV_SHIFT; 661 break; 662 default: 663 return -ENOENT; 664 } 665 666 div = (readl(&cru->clksel_con[con]) & mask) >> shift; 667 return DIV_TO_RATE(priv->cpll_hz, div); 668 } 669 670 static ulong rk3568_cpll_div_set_rate(struct rk3568_clk_priv *priv, 671 ulong clk_id, ulong rate) 672 { 673 struct rk3568_cru *cru = priv->cru; 674 int div, mask, shift, con; 675 676 switch (clk_id) { 677 case CPLL_500M: 678 con = 78; 679 mask = CPLL_500M_DIV_MASK; 680 shift = CPLL_500M_DIV_SHIFT; 681 break; 682 case CPLL_333M: 683 con = 79; 684 mask = CPLL_333M_DIV_MASK; 685 shift = CPLL_333M_DIV_SHIFT; 686 break; 687 case CPLL_250M: 688 con = 79; 689 mask = CPLL_250M_DIV_MASK; 690 shift = CPLL_250M_DIV_SHIFT; 691 break; 692 case CPLL_125M: 693 con = 80; 694 mask = CPLL_125M_DIV_MASK; 695 shift = CPLL_125M_DIV_SHIFT; 696 break; 697 case CPLL_100M: 698 con = 82; 699 mask = CPLL_100M_DIV_MASK; 700 shift = CPLL_100M_DIV_SHIFT; 701 break; 702 case CPLL_62P5M: 703 con = 80; 704 mask = CPLL_62P5M_DIV_MASK; 705 shift = CPLL_62P5M_DIV_SHIFT; 706 break; 707 case CPLL_50M: 708 con = 81; 709 mask = CPLL_50M_DIV_MASK; 710 shift = CPLL_50M_DIV_SHIFT; 711 break; 712 case CPLL_25M: 713 con = 81; 714 mask = CPLL_25M_DIV_MASK; 715 shift = CPLL_25M_DIV_SHIFT; 716 break; 717 default: 718 return -ENOENT; 719 } 720 721 div = DIV_ROUND_UP(priv->cpll_hz, rate); 722 assert(div - 1 <= 31); 723 rk_clrsetreg(&cru->clksel_con[con], 724 mask, (div - 1) << shift); 725 return rk3568_cpll_div_get_rate(priv, clk_id); 726 } 727 728 static ulong rk3568_bus_get_clk(struct rk3568_clk_priv *priv, ulong clk_id) 729 { 730 struct rk3568_cru *cru = priv->cru; 731 u32 con, sel, rate; 732 733 switch (clk_id) { 734 case ACLK_BUS: 735 con = readl(&cru->clksel_con[50]); 736 sel = (con & ACLK_BUS_SEL_MASK) >> ACLK_BUS_SEL_SHIFT; 737 if (sel == ACLK_BUS_SEL_200M) 738 rate = 200 * MHz; 739 else if (sel == ACLK_BUS_SEL_150M) 740 rate = 150 * MHz; 741 else if (sel == ACLK_BUS_SEL_100M) 742 rate = 100 * MHz; 743 else 744 rate = OSC_HZ; 745 break; 746 case PCLK_BUS: 747 case PCLK_WDT_NS: 748 con = readl(&cru->clksel_con[50]); 749 sel = (con & PCLK_BUS_SEL_MASK) >> PCLK_BUS_SEL_SHIFT; 750 if (sel == PCLK_BUS_SEL_100M) 751 rate = 100 * MHz; 752 else if (sel == PCLK_BUS_SEL_75M) 753 rate = 75 * MHz; 754 else if (sel == PCLK_BUS_SEL_50M) 755 rate = 50 * MHz; 756 else 757 rate = OSC_HZ; 758 break; 759 default: 760 return -ENOENT; 761 } 762 763 return rate; 764 } 765 766 static ulong rk3568_bus_set_clk(struct rk3568_clk_priv *priv, 767 ulong clk_id, ulong rate) 768 { 769 struct rk3568_cru *cru = priv->cru; 770 int src_clk; 771 772 switch (clk_id) { 773 case ACLK_BUS: 774 if (rate == 200 * MHz) 775 src_clk = ACLK_BUS_SEL_200M; 776 else if (rate == 150 * MHz) 777 src_clk = ACLK_BUS_SEL_150M; 778 else if (rate == 100 * MHz) 779 src_clk = ACLK_BUS_SEL_100M; 780 else 781 src_clk = ACLK_BUS_SEL_24M; 782 rk_clrsetreg(&cru->clksel_con[50], 783 ACLK_BUS_SEL_MASK, 784 src_clk << ACLK_BUS_SEL_SHIFT); 785 break; 786 case PCLK_BUS: 787 case PCLK_WDT_NS: 788 if (rate == 100 * MHz) 789 src_clk = PCLK_BUS_SEL_100M; 790 else if (rate == 75 * MHz) 791 src_clk = PCLK_BUS_SEL_75M; 792 else if (rate == 50 * MHz) 793 src_clk = PCLK_BUS_SEL_50M; 794 else 795 src_clk = PCLK_BUS_SEL_24M; 796 rk_clrsetreg(&cru->clksel_con[50], 797 PCLK_BUS_SEL_MASK, 798 src_clk << PCLK_BUS_SEL_SHIFT); 799 break; 800 801 default: 802 printf("do not support this bus freq\n"); 803 return -EINVAL; 804 } 805 806 return rk3568_bus_get_clk(priv, clk_id); 807 } 808 809 static ulong rk3568_perimid_get_clk(struct rk3568_clk_priv *priv, ulong clk_id) 810 { 811 struct rk3568_cru *cru = priv->cru; 812 u32 con, sel, rate; 813 814 switch (clk_id) { 815 case ACLK_PERIMID: 816 con = readl(&cru->clksel_con[10]); 817 sel = (con & ACLK_PERIMID_SEL_MASK) >> ACLK_PERIMID_SEL_SHIFT; 818 if (sel == ACLK_PERIMID_SEL_300M) 819 rate = 300 * MHz; 820 else if (sel == ACLK_PERIMID_SEL_200M) 821 rate = 200 * MHz; 822 else if (sel == ACLK_PERIMID_SEL_100M) 823 rate = 100 * MHz; 824 else 825 rate = OSC_HZ; 826 break; 827 case HCLK_PERIMID: 828 con = readl(&cru->clksel_con[10]); 829 sel = (con & HCLK_PERIMID_SEL_MASK) >> HCLK_PERIMID_SEL_SHIFT; 830 if (sel == HCLK_PERIMID_SEL_150M) 831 rate = 150 * MHz; 832 else if (sel == HCLK_PERIMID_SEL_100M) 833 rate = 100 * MHz; 834 else if (sel == HCLK_PERIMID_SEL_75M) 835 rate = 75 * MHz; 836 else 837 rate = OSC_HZ; 838 break; 839 default: 840 return -ENOENT; 841 } 842 843 return rate; 844 } 845 846 static ulong rk3568_perimid_set_clk(struct rk3568_clk_priv *priv, 847 ulong clk_id, ulong rate) 848 { 849 struct rk3568_cru *cru = priv->cru; 850 int src_clk; 851 852 switch (clk_id) { 853 case ACLK_PERIMID: 854 if (rate == 300 * MHz) 855 src_clk = ACLK_PERIMID_SEL_300M; 856 else if (rate == 200 * MHz) 857 src_clk = ACLK_PERIMID_SEL_200M; 858 else if (rate == 100 * MHz) 859 src_clk = ACLK_PERIMID_SEL_100M; 860 else 861 src_clk = ACLK_PERIMID_SEL_24M; 862 rk_clrsetreg(&cru->clksel_con[10], 863 ACLK_PERIMID_SEL_MASK, 864 src_clk << ACLK_PERIMID_SEL_SHIFT); 865 break; 866 case HCLK_PERIMID: 867 if (rate == 150 * MHz) 868 src_clk = HCLK_PERIMID_SEL_150M; 869 else if (rate == 100 * MHz) 870 src_clk = HCLK_PERIMID_SEL_100M; 871 else if (rate == 75 * MHz) 872 src_clk = HCLK_PERIMID_SEL_75M; 873 else 874 src_clk = HCLK_PERIMID_SEL_24M; 875 rk_clrsetreg(&cru->clksel_con[10], 876 HCLK_PERIMID_SEL_MASK, 877 src_clk << HCLK_PERIMID_SEL_SHIFT); 878 break; 879 880 default: 881 printf("do not support this permid freq\n"); 882 return -EINVAL; 883 } 884 885 return rk3568_perimid_get_clk(priv, clk_id); 886 } 887 888 static ulong rk3568_top_get_clk(struct rk3568_clk_priv *priv, ulong clk_id) 889 { 890 struct rk3568_cru *cru = priv->cru; 891 u32 con, sel, rate; 892 893 switch (clk_id) { 894 case ACLK_TOP_HIGH: 895 con = readl(&cru->clksel_con[73]); 896 sel = (con & ACLK_TOP_HIGH_SEL_MASK) >> ACLK_TOP_HIGH_SEL_SHIFT; 897 if (sel == ACLK_TOP_HIGH_SEL_500M) 898 rate = 500 * MHz; 899 else if (sel == ACLK_TOP_HIGH_SEL_400M) 900 rate = 400 * MHz; 901 else if (sel == ACLK_TOP_HIGH_SEL_300M) 902 rate = 300 * MHz; 903 else 904 rate = OSC_HZ; 905 break; 906 case ACLK_TOP_LOW: 907 con = readl(&cru->clksel_con[73]); 908 sel = (con & ACLK_TOP_LOW_SEL_MASK) >> ACLK_TOP_LOW_SEL_SHIFT; 909 if (sel == ACLK_TOP_LOW_SEL_400M) 910 rate = 400 * MHz; 911 else if (sel == ACLK_TOP_LOW_SEL_300M) 912 rate = 300 * MHz; 913 else if (sel == ACLK_TOP_LOW_SEL_200M) 914 rate = 200 * MHz; 915 else 916 rate = OSC_HZ; 917 break; 918 case HCLK_TOP: 919 con = readl(&cru->clksel_con[73]); 920 sel = (con & HCLK_TOP_SEL_MASK) >> HCLK_TOP_SEL_SHIFT; 921 if (sel == HCLK_TOP_SEL_150M) 922 rate = 150 * MHz; 923 else if (sel == HCLK_TOP_SEL_100M) 924 rate = 100 * MHz; 925 else if (sel == HCLK_TOP_SEL_75M) 926 rate = 75 * MHz; 927 else 928 rate = OSC_HZ; 929 break; 930 case PCLK_TOP: 931 con = readl(&cru->clksel_con[73]); 932 sel = (con & PCLK_TOP_SEL_MASK) >> PCLK_TOP_SEL_SHIFT; 933 if (sel == PCLK_TOP_SEL_100M) 934 rate = 100 * MHz; 935 else if (sel == PCLK_TOP_SEL_75M) 936 rate = 75 * MHz; 937 else if (sel == PCLK_TOP_SEL_50M) 938 rate = 50 * MHz; 939 else 940 rate = OSC_HZ; 941 break; 942 default: 943 return -ENOENT; 944 } 945 946 return rate; 947 } 948 949 static ulong rk3568_top_set_clk(struct rk3568_clk_priv *priv, 950 ulong clk_id, ulong rate) 951 { 952 struct rk3568_cru *cru = priv->cru; 953 int src_clk; 954 955 switch (clk_id) { 956 case ACLK_TOP_HIGH: 957 if (rate == 500 * MHz) 958 src_clk = ACLK_TOP_HIGH_SEL_500M; 959 else if (rate == 400 * MHz) 960 src_clk = ACLK_TOP_HIGH_SEL_400M; 961 else if (rate == 300 * MHz) 962 src_clk = ACLK_TOP_HIGH_SEL_300M; 963 else 964 src_clk = ACLK_TOP_HIGH_SEL_24M; 965 rk_clrsetreg(&cru->clksel_con[73], 966 ACLK_TOP_HIGH_SEL_MASK, 967 src_clk << ACLK_TOP_HIGH_SEL_SHIFT); 968 break; 969 case ACLK_TOP_LOW: 970 if (rate == 400 * MHz) 971 src_clk = ACLK_TOP_LOW_SEL_400M; 972 else if (rate == 300 * MHz) 973 src_clk = ACLK_TOP_LOW_SEL_300M; 974 else if (rate == 200 * MHz) 975 src_clk = ACLK_TOP_LOW_SEL_200M; 976 else 977 src_clk = ACLK_TOP_LOW_SEL_24M; 978 rk_clrsetreg(&cru->clksel_con[73], 979 ACLK_TOP_LOW_SEL_MASK, 980 src_clk << ACLK_TOP_LOW_SEL_SHIFT); 981 break; 982 case HCLK_TOP: 983 if (rate == 150 * MHz) 984 src_clk = HCLK_TOP_SEL_150M; 985 else if (rate == 100 * MHz) 986 src_clk = HCLK_TOP_SEL_100M; 987 else if (rate == 75 * MHz) 988 src_clk = HCLK_TOP_SEL_75M; 989 else 990 src_clk = HCLK_TOP_SEL_24M; 991 rk_clrsetreg(&cru->clksel_con[73], 992 HCLK_TOP_SEL_MASK, 993 src_clk << HCLK_TOP_SEL_SHIFT); 994 break; 995 case PCLK_TOP: 996 if (rate == 100 * MHz) 997 src_clk = PCLK_TOP_SEL_100M; 998 else if (rate == 75 * MHz) 999 src_clk = PCLK_TOP_SEL_75M; 1000 else if (rate == 50 * MHz) 1001 src_clk = PCLK_TOP_SEL_50M; 1002 else 1003 src_clk = PCLK_TOP_SEL_24M; 1004 rk_clrsetreg(&cru->clksel_con[73], 1005 PCLK_TOP_SEL_MASK, 1006 src_clk << PCLK_TOP_SEL_SHIFT); 1007 break; 1008 1009 default: 1010 printf("do not support this permid freq\n"); 1011 return -EINVAL; 1012 } 1013 1014 return rk3568_top_get_clk(priv, clk_id); 1015 } 1016 1017 static ulong rk3568_i2c_get_clk(struct rk3568_clk_priv *priv, ulong clk_id) 1018 { 1019 struct rk3568_cru *cru = priv->cru; 1020 u32 sel, con; 1021 ulong rate; 1022 1023 switch (clk_id) { 1024 case CLK_I2C1: 1025 case CLK_I2C2: 1026 case CLK_I2C3: 1027 case CLK_I2C4: 1028 case CLK_I2C5: 1029 con = readl(&cru->clksel_con[71]); 1030 sel = (con & CLK_I2C_SEL_MASK) >> CLK_I2C_SEL_SHIFT; 1031 if (sel == CLK_I2C_SEL_200M) 1032 rate = 200 * MHz; 1033 else if (sel == CLK_I2C_SEL_100M) 1034 rate = 100 * MHz; 1035 else if (sel == CLK_I2C_SEL_CPLL_100M) 1036 rate = 100 * MHz; 1037 else 1038 rate = OSC_HZ; 1039 break; 1040 default: 1041 return -ENOENT; 1042 } 1043 1044 return rate; 1045 } 1046 1047 static ulong rk3568_i2c_set_clk(struct rk3568_clk_priv *priv, ulong clk_id, 1048 ulong rate) 1049 { 1050 struct rk3568_cru *cru = priv->cru; 1051 int src_clk; 1052 1053 if (rate == 200 * MHz) 1054 src_clk = CLK_I2C_SEL_200M; 1055 else if (rate == 100 * MHz) 1056 src_clk = CLK_I2C_SEL_100M; 1057 else 1058 src_clk = CLK_I2C_SEL_24M; 1059 1060 switch (clk_id) { 1061 case CLK_I2C1: 1062 case CLK_I2C2: 1063 case CLK_I2C3: 1064 case CLK_I2C4: 1065 case CLK_I2C5: 1066 rk_clrsetreg(&cru->clksel_con[71], CLK_I2C_SEL_MASK, 1067 src_clk << CLK_I2C_SEL_SHIFT); 1068 break; 1069 default: 1070 return -ENOENT; 1071 } 1072 1073 return rk3568_i2c_get_clk(priv, clk_id); 1074 } 1075 1076 static ulong rk3568_spi_get_clk(struct rk3568_clk_priv *priv, ulong clk_id) 1077 { 1078 struct rk3568_cru *cru = priv->cru; 1079 u32 sel, con; 1080 1081 con = readl(&cru->clksel_con[72]); 1082 1083 switch (clk_id) { 1084 case CLK_SPI0: 1085 sel = (con & CLK_SPI0_SEL_MASK) >> CLK_SPI0_SEL_SHIFT; 1086 break; 1087 case CLK_SPI1: 1088 sel = (con & CLK_SPI1_SEL_MASK) >> CLK_SPI1_SEL_SHIFT; 1089 break; 1090 case CLK_SPI2: 1091 sel = (con & CLK_SPI2_SEL_MASK) >> CLK_SPI2_SEL_SHIFT; 1092 break; 1093 case CLK_SPI3: 1094 sel = (con & CLK_SPI3_SEL_MASK) >> CLK_SPI3_SEL_SHIFT; 1095 break; 1096 default: 1097 return -ENOENT; 1098 } 1099 1100 switch (sel) { 1101 case CLK_SPI_SEL_200M: 1102 return 200 * MHz; 1103 case CLK_SPI_SEL_24M: 1104 return OSC_HZ; 1105 case CLK_SPI_SEL_CPLL_100M: 1106 return 100 * MHz; 1107 default: 1108 return -ENOENT; 1109 } 1110 } 1111 1112 static ulong rk3568_spi_set_clk(struct rk3568_clk_priv *priv, 1113 ulong clk_id, ulong rate) 1114 { 1115 struct rk3568_cru *cru = priv->cru; 1116 int src_clk; 1117 1118 if (rate == 200 * MHz) 1119 src_clk = CLK_SPI_SEL_200M; 1120 else if (rate == 100 * MHz) 1121 src_clk = CLK_SPI_SEL_CPLL_100M; 1122 else 1123 src_clk = CLK_SPI_SEL_24M; 1124 1125 switch (clk_id) { 1126 case CLK_SPI0: 1127 rk_clrsetreg(&cru->clksel_con[72], 1128 CLK_SPI0_SEL_MASK, 1129 src_clk << CLK_SPI0_SEL_SHIFT); 1130 break; 1131 case CLK_SPI1: 1132 rk_clrsetreg(&cru->clksel_con[72], 1133 CLK_SPI1_SEL_MASK, 1134 src_clk << CLK_SPI1_SEL_SHIFT); 1135 break; 1136 case CLK_SPI2: 1137 rk_clrsetreg(&cru->clksel_con[72], 1138 CLK_SPI2_SEL_MASK, 1139 src_clk << CLK_SPI2_SEL_SHIFT); 1140 break; 1141 case CLK_SPI3: 1142 rk_clrsetreg(&cru->clksel_con[72], 1143 CLK_SPI3_SEL_MASK, 1144 src_clk << CLK_SPI3_SEL_SHIFT); 1145 break; 1146 default: 1147 return -ENOENT; 1148 } 1149 1150 return rk3568_spi_get_clk(priv, clk_id); 1151 } 1152 1153 static ulong rk3568_pwm_get_clk(struct rk3568_clk_priv *priv, ulong clk_id) 1154 { 1155 struct rk3568_cru *cru = priv->cru; 1156 u32 sel, con; 1157 1158 con = readl(&cru->clksel_con[72]); 1159 1160 switch (clk_id) { 1161 case CLK_PWM1: 1162 sel = (con & CLK_PWM1_SEL_MASK) >> CLK_PWM3_SEL_SHIFT; 1163 break; 1164 case CLK_PWM2: 1165 sel = (con & CLK_PWM2_SEL_MASK) >> CLK_PWM2_SEL_SHIFT; 1166 break; 1167 case CLK_PWM3: 1168 sel = (con & CLK_PWM3_SEL_MASK) >> CLK_PWM3_SEL_SHIFT; 1169 break; 1170 default: 1171 return -ENOENT; 1172 } 1173 1174 switch (sel) { 1175 case CLK_PWM_SEL_100M: 1176 return 100 * MHz; 1177 case CLK_PWM_SEL_24M: 1178 return OSC_HZ; 1179 case CLK_PWM_SEL_CPLL_100M: 1180 return 100 * MHz; 1181 default: 1182 return -ENOENT; 1183 } 1184 } 1185 1186 static ulong rk3568_pwm_set_clk(struct rk3568_clk_priv *priv, 1187 ulong clk_id, ulong rate) 1188 { 1189 struct rk3568_cru *cru = priv->cru; 1190 int src_clk; 1191 1192 if (rate == 100 * MHz) 1193 src_clk = CLK_PWM_SEL_100M; 1194 else 1195 src_clk = CLK_PWM_SEL_24M; 1196 1197 switch (clk_id) { 1198 case CLK_PWM1: 1199 rk_clrsetreg(&cru->clksel_con[72], 1200 CLK_PWM1_SEL_MASK, 1201 src_clk << CLK_PWM1_SEL_SHIFT); 1202 break; 1203 case CLK_PWM2: 1204 rk_clrsetreg(&cru->clksel_con[72], 1205 CLK_PWM2_SEL_MASK, 1206 src_clk << CLK_PWM2_SEL_SHIFT); 1207 break; 1208 case CLK_PWM3: 1209 rk_clrsetreg(&cru->clksel_con[72], 1210 CLK_PWM3_SEL_MASK, 1211 src_clk << CLK_PWM3_SEL_SHIFT); 1212 break; 1213 default: 1214 return -ENOENT; 1215 } 1216 1217 return rk3568_pwm_get_clk(priv, clk_id); 1218 } 1219 1220 static ulong rk3568_adc_get_clk(struct rk3568_clk_priv *priv, ulong clk_id) 1221 { 1222 struct rk3568_cru *cru = priv->cru; 1223 u32 div, sel, con, prate; 1224 1225 switch (clk_id) { 1226 case CLK_SARADC: 1227 return OSC_HZ; 1228 case CLK_TSADC_TSEN: 1229 con = readl(&cru->clksel_con[51]); 1230 div = (con & CLK_TSADC_TSEN_DIV_MASK) >> 1231 CLK_TSADC_TSEN_DIV_SHIFT; 1232 sel = (con & CLK_TSADC_TSEN_SEL_MASK) >> 1233 CLK_TSADC_TSEN_SEL_SHIFT; 1234 if (sel == CLK_TSADC_TSEN_SEL_24M) 1235 prate = OSC_HZ; 1236 else 1237 prate = 100 * MHz; 1238 return DIV_TO_RATE(prate, div); 1239 case CLK_TSADC: 1240 con = readl(&cru->clksel_con[51]); 1241 div = (con & CLK_TSADC_DIV_MASK) >> CLK_TSADC_DIV_SHIFT; 1242 prate = rk3568_adc_get_clk(priv, CLK_TSADC_TSEN); 1243 return DIV_TO_RATE(prate, div); 1244 default: 1245 return -ENOENT; 1246 } 1247 } 1248 1249 static ulong rk3568_adc_set_clk(struct rk3568_clk_priv *priv, 1250 ulong clk_id, ulong rate) 1251 { 1252 struct rk3568_cru *cru = priv->cru; 1253 int src_clk_div; 1254 ulong prate = 0; 1255 1256 switch (clk_id) { 1257 case CLK_SARADC: 1258 return OSC_HZ; 1259 case CLK_TSADC_TSEN: 1260 if (!(OSC_HZ % rate)) { 1261 src_clk_div = DIV_ROUND_UP(OSC_HZ, rate); 1262 assert(src_clk_div - 1 <= 7); 1263 rk_clrsetreg(&cru->clksel_con[51], 1264 CLK_TSADC_TSEN_SEL_MASK | 1265 CLK_TSADC_TSEN_DIV_MASK, 1266 (CLK_TSADC_TSEN_SEL_24M << 1267 CLK_TSADC_TSEN_SEL_SHIFT) | 1268 (src_clk_div - 1) << 1269 CLK_TSADC_TSEN_DIV_SHIFT); 1270 } else { 1271 src_clk_div = DIV_ROUND_UP(100 * MHz, rate); 1272 assert(src_clk_div - 1 <= 7); 1273 rk_clrsetreg(&cru->clksel_con[51], 1274 CLK_TSADC_TSEN_SEL_MASK | 1275 CLK_TSADC_TSEN_DIV_MASK, 1276 (CLK_TSADC_TSEN_SEL_100M << 1277 CLK_TSADC_TSEN_SEL_SHIFT) | 1278 (src_clk_div - 1) << 1279 CLK_TSADC_TSEN_DIV_SHIFT); 1280 } 1281 break; 1282 case CLK_TSADC: 1283 prate = rk3568_adc_get_clk(priv, CLK_TSADC_TSEN); 1284 src_clk_div = DIV_ROUND_UP(prate, rate); 1285 assert(src_clk_div - 1 <= 128); 1286 rk_clrsetreg(&cru->clksel_con[51], 1287 CLK_TSADC_DIV_MASK, 1288 (src_clk_div - 1) << CLK_TSADC_DIV_SHIFT); 1289 break; 1290 default: 1291 return -ENOENT; 1292 } 1293 return rk3568_adc_get_clk(priv, clk_id); 1294 } 1295 1296 static ulong rk3568_crypto_get_rate(struct rk3568_clk_priv *priv, ulong clk_id) 1297 { 1298 struct rk3568_cru *cru = priv->cru; 1299 u32 sel, con; 1300 1301 switch (clk_id) { 1302 case ACLK_SECURE_FLASH: 1303 case ACLK_CRYPTO_NS: 1304 con = readl(&cru->clksel_con[27]); 1305 sel = (con & ACLK_SECURE_FLASH_SEL_MASK) >> 1306 ACLK_SECURE_FLASH_SEL_SHIFT; 1307 if (sel == ACLK_SECURE_FLASH_SEL_200M) 1308 return 200 * MHz; 1309 else if (sel == ACLK_SECURE_FLASH_SEL_150M) 1310 return 150 * MHz; 1311 else if (sel == ACLK_SECURE_FLASH_SEL_100M) 1312 return 100 * MHz; 1313 else 1314 return 24 * MHz; 1315 case HCLK_SECURE_FLASH: 1316 case HCLK_CRYPTO_NS: 1317 case CLK_CRYPTO_NS_RNG: 1318 con = readl(&cru->clksel_con[27]); 1319 sel = (con & HCLK_SECURE_FLASH_SEL_MASK) >> 1320 HCLK_SECURE_FLASH_SEL_SHIFT; 1321 if (sel == HCLK_SECURE_FLASH_SEL_150M) 1322 return 150 * MHz; 1323 else if (sel == HCLK_SECURE_FLASH_SEL_100M) 1324 return 100 * MHz; 1325 else if (sel == HCLK_SECURE_FLASH_SEL_75M) 1326 return 75 * MHz; 1327 else 1328 return 24 * MHz; 1329 case CLK_CRYPTO_NS_CORE: 1330 con = readl(&cru->clksel_con[27]); 1331 sel = (con & CLK_CRYPTO_CORE_SEL_MASK) >> 1332 CLK_CRYPTO_CORE_SEL_SHIFT; 1333 if (sel == CLK_CRYPTO_CORE_SEL_200M) 1334 return 200 * MHz; 1335 else if (sel == CLK_CRYPTO_CORE_SEL_150M) 1336 return 150 * MHz; 1337 else 1338 return 100 * MHz; 1339 case CLK_CRYPTO_NS_PKA: 1340 con = readl(&cru->clksel_con[27]); 1341 sel = (con & CLK_CRYPTO_PKA_SEL_MASK) >> 1342 CLK_CRYPTO_PKA_SEL_SHIFT; 1343 if (sel == CLK_CRYPTO_PKA_SEL_300M) 1344 return 300 * MHz; 1345 else if (sel == CLK_CRYPTO_PKA_SEL_200M) 1346 return 200 * MHz; 1347 else 1348 return 100 * MHz; 1349 default: 1350 return -ENOENT; 1351 } 1352 } 1353 1354 static ulong rk3568_crypto_set_rate(struct rk3568_clk_priv *priv, 1355 ulong clk_id, ulong rate) 1356 { 1357 struct rk3568_cru *cru = priv->cru; 1358 u32 src_clk, mask, shift; 1359 1360 switch (clk_id) { 1361 case ACLK_SECURE_FLASH: 1362 case ACLK_CRYPTO_NS: 1363 mask = ACLK_SECURE_FLASH_SEL_MASK; 1364 shift = ACLK_SECURE_FLASH_SEL_SHIFT; 1365 if (rate == 200 * MHz) 1366 src_clk = ACLK_SECURE_FLASH_SEL_200M; 1367 else if (rate == 150 * MHz) 1368 src_clk = ACLK_SECURE_FLASH_SEL_150M; 1369 else if (rate == 100 * MHz) 1370 src_clk = ACLK_SECURE_FLASH_SEL_100M; 1371 else 1372 src_clk = ACLK_SECURE_FLASH_SEL_24M; 1373 break; 1374 case HCLK_SECURE_FLASH: 1375 case HCLK_CRYPTO_NS: 1376 case CLK_CRYPTO_NS_RNG: 1377 mask = HCLK_SECURE_FLASH_SEL_MASK; 1378 shift = HCLK_SECURE_FLASH_SEL_SHIFT; 1379 if (rate == 150 * MHz) 1380 src_clk = HCLK_SECURE_FLASH_SEL_150M; 1381 else if (rate == 100 * MHz) 1382 src_clk = HCLK_SECURE_FLASH_SEL_100M; 1383 else if (rate == 75 * MHz) 1384 src_clk = HCLK_SECURE_FLASH_SEL_75M; 1385 else 1386 src_clk = HCLK_SECURE_FLASH_SEL_24M; 1387 break; 1388 case CLK_CRYPTO_NS_CORE: 1389 mask = CLK_CRYPTO_CORE_SEL_MASK; 1390 shift = CLK_CRYPTO_CORE_SEL_SHIFT; 1391 if (rate == 200 * MHz) 1392 src_clk = CLK_CRYPTO_CORE_SEL_200M; 1393 else if (rate == 150 * MHz) 1394 src_clk = CLK_CRYPTO_CORE_SEL_150M; 1395 else 1396 src_clk = CLK_CRYPTO_CORE_SEL_100M; 1397 break; 1398 case CLK_CRYPTO_NS_PKA: 1399 mask = CLK_CRYPTO_PKA_SEL_MASK; 1400 shift = CLK_CRYPTO_PKA_SEL_SHIFT; 1401 if (rate == 300 * MHz) 1402 src_clk = CLK_CRYPTO_PKA_SEL_300M; 1403 else if (rate == 200 * MHz) 1404 src_clk = CLK_CRYPTO_PKA_SEL_200M; 1405 else 1406 src_clk = CLK_CRYPTO_PKA_SEL_100M; 1407 break; 1408 default: 1409 return -ENOENT; 1410 } 1411 1412 rk_clrsetreg(&cru->clksel_con[27], mask, src_clk << shift); 1413 1414 return rk3568_crypto_get_rate(priv, clk_id); 1415 } 1416 1417 static ulong rk3568_sdmmc_get_clk(struct rk3568_clk_priv *priv, ulong clk_id) 1418 { 1419 struct rk3568_cru *cru = priv->cru; 1420 u32 sel, con; 1421 1422 switch (clk_id) { 1423 case HCLK_SDMMC0: 1424 case CLK_SDMMC0: 1425 con = readl(&cru->clksel_con[30]); 1426 sel = (con & CLK_SDMMC0_SEL_MASK) >> CLK_SDMMC0_SEL_SHIFT; 1427 break; 1428 case CLK_SDMMC1: 1429 con = readl(&cru->clksel_con[30]); 1430 sel = (con & CLK_SDMMC1_SEL_MASK) >> CLK_SDMMC1_SEL_SHIFT; 1431 break; 1432 case CLK_SDMMC2: 1433 con = readl(&cru->clksel_con[32]); 1434 sel = (con & CLK_SDMMC2_SEL_MASK) >> CLK_SDMMC2_SEL_SHIFT; 1435 break; 1436 default: 1437 return -ENOENT; 1438 } 1439 1440 switch (sel) { 1441 case CLK_SDMMC_SEL_24M: 1442 return OSC_HZ; 1443 case CLK_SDMMC_SEL_400M: 1444 return 400 * MHz; 1445 case CLK_SDMMC_SEL_300M: 1446 return 300 * MHz; 1447 case CLK_SDMMC_SEL_100M: 1448 return 100 * MHz; 1449 case CLK_SDMMC_SEL_50M: 1450 return 50 * MHz; 1451 case CLK_SDMMC_SEL_750K: 1452 return 750 * KHz; 1453 default: 1454 return -ENOENT; 1455 } 1456 } 1457 1458 static ulong rk3568_sdmmc_set_clk(struct rk3568_clk_priv *priv, 1459 ulong clk_id, ulong rate) 1460 { 1461 struct rk3568_cru *cru = priv->cru; 1462 int src_clk; 1463 1464 switch (rate) { 1465 case OSC_HZ: 1466 src_clk = CLK_SDMMC_SEL_24M; 1467 break; 1468 case 400 * MHz: 1469 src_clk = CLK_SDMMC_SEL_400M; 1470 break; 1471 case 300 * MHz: 1472 src_clk = CLK_SDMMC_SEL_300M; 1473 break; 1474 case 100 * MHz: 1475 src_clk = CLK_SDMMC_SEL_100M; 1476 break; 1477 case 52 * MHz: 1478 case 50 * MHz: 1479 src_clk = CLK_SDMMC_SEL_50M; 1480 break; 1481 case 750 * KHz: 1482 case 400 * KHz: 1483 src_clk = CLK_SDMMC_SEL_750K; 1484 break; 1485 default: 1486 return -ENOENT; 1487 } 1488 1489 switch (clk_id) { 1490 case HCLK_SDMMC0: 1491 case CLK_SDMMC0: 1492 rk_clrsetreg(&cru->clksel_con[30], 1493 CLK_SDMMC0_SEL_MASK, 1494 src_clk << CLK_SDMMC0_SEL_SHIFT); 1495 break; 1496 case CLK_SDMMC1: 1497 rk_clrsetreg(&cru->clksel_con[30], 1498 CLK_SDMMC1_SEL_MASK, 1499 src_clk << CLK_SDMMC1_SEL_SHIFT); 1500 break; 1501 case CLK_SDMMC2: 1502 rk_clrsetreg(&cru->clksel_con[32], 1503 CLK_SDMMC2_SEL_MASK, 1504 src_clk << CLK_SDMMC2_SEL_SHIFT); 1505 break; 1506 default: 1507 return -ENOENT; 1508 } 1509 1510 return rk3568_sdmmc_get_clk(priv, clk_id); 1511 } 1512 1513 static ulong rk3568_sfc_get_clk(struct rk3568_clk_priv *priv) 1514 { 1515 struct rk3568_cru *cru = priv->cru; 1516 u32 sel, con; 1517 1518 con = readl(&cru->clksel_con[28]); 1519 sel = (con & SCLK_SFC_SEL_MASK) >> SCLK_SFC_SEL_SHIFT; 1520 switch (sel) { 1521 case SCLK_SFC_SEL_24M: 1522 return OSC_HZ; 1523 case SCLK_SFC_SEL_50M: 1524 return 50 * MHz; 1525 case SCLK_SFC_SEL_75M: 1526 return 75 * MHz; 1527 case SCLK_SFC_SEL_100M: 1528 return 100 * MHz; 1529 case SCLK_SFC_SEL_125M: 1530 return 125 * MHz; 1531 case SCLK_SFC_SEL_150M: 1532 return 150 * KHz; 1533 default: 1534 return -ENOENT; 1535 } 1536 } 1537 1538 static ulong rk3568_sfc_set_clk(struct rk3568_clk_priv *priv, ulong rate) 1539 { 1540 struct rk3568_cru *cru = priv->cru; 1541 int src_clk; 1542 1543 switch (rate) { 1544 case OSC_HZ: 1545 src_clk = SCLK_SFC_SEL_24M; 1546 break; 1547 case 50 * MHz: 1548 src_clk = SCLK_SFC_SEL_50M; 1549 break; 1550 case 75 * MHz: 1551 src_clk = SCLK_SFC_SEL_75M; 1552 break; 1553 case 100 * MHz: 1554 src_clk = SCLK_SFC_SEL_100M; 1555 break; 1556 case 125 * MHz: 1557 src_clk = SCLK_SFC_SEL_125M; 1558 break; 1559 case 150 * KHz: 1560 src_clk = SCLK_SFC_SEL_150M; 1561 break; 1562 default: 1563 return -ENOENT; 1564 } 1565 1566 rk_clrsetreg(&cru->clksel_con[28], 1567 SCLK_SFC_SEL_MASK, 1568 src_clk << SCLK_SFC_SEL_SHIFT); 1569 1570 return rk3568_sfc_get_clk(priv); 1571 } 1572 1573 static ulong rk3568_nand_get_clk(struct rk3568_clk_priv *priv) 1574 { 1575 struct rk3568_cru *cru = priv->cru; 1576 u32 sel, con; 1577 1578 con = readl(&cru->clksel_con[28]); 1579 sel = (con & NCLK_NANDC_SEL_MASK) >> NCLK_NANDC_SEL_SHIFT; 1580 switch (sel) { 1581 case NCLK_NANDC_SEL_200M: 1582 return 200 * MHz; 1583 case NCLK_NANDC_SEL_150M: 1584 return 150 * MHz; 1585 case NCLK_NANDC_SEL_100M: 1586 return 100 * MHz; 1587 case NCLK_NANDC_SEL_24M: 1588 return OSC_HZ; 1589 default: 1590 return -ENOENT; 1591 } 1592 } 1593 1594 static ulong rk3568_nand_set_clk(struct rk3568_clk_priv *priv, ulong rate) 1595 { 1596 struct rk3568_cru *cru = priv->cru; 1597 int src_clk; 1598 1599 switch (rate) { 1600 case OSC_HZ: 1601 src_clk = NCLK_NANDC_SEL_24M; 1602 break; 1603 case 100 * MHz: 1604 src_clk = NCLK_NANDC_SEL_100M; 1605 break; 1606 case 150 * MHz: 1607 src_clk = NCLK_NANDC_SEL_150M; 1608 break; 1609 case 200 * MHz: 1610 src_clk = NCLK_NANDC_SEL_200M; 1611 break; 1612 default: 1613 return -ENOENT; 1614 } 1615 1616 rk_clrsetreg(&cru->clksel_con[28], 1617 NCLK_NANDC_SEL_MASK, 1618 src_clk << NCLK_NANDC_SEL_SHIFT); 1619 1620 return rk3568_nand_get_clk(priv); 1621 } 1622 1623 static ulong rk3568_emmc_get_clk(struct rk3568_clk_priv *priv) 1624 { 1625 struct rk3568_cru *cru = priv->cru; 1626 u32 sel, con; 1627 1628 con = readl(&cru->clksel_con[28]); 1629 sel = (con & CCLK_EMMC_SEL_MASK) >> CCLK_EMMC_SEL_SHIFT; 1630 switch (sel) { 1631 case CCLK_EMMC_SEL_200M: 1632 return 200 * MHz; 1633 case CCLK_EMMC_SEL_150M: 1634 return 150 * MHz; 1635 case CCLK_EMMC_SEL_100M: 1636 return 100 * MHz; 1637 case CCLK_EMMC_SEL_50M: 1638 return 50 * MHz; 1639 case CCLK_EMMC_SEL_375K: 1640 return 375 * KHz; 1641 case CCLK_EMMC_SEL_24M: 1642 return OSC_HZ; 1643 default: 1644 return -ENOENT; 1645 } 1646 } 1647 1648 static ulong rk3568_emmc_set_clk(struct rk3568_clk_priv *priv, ulong rate) 1649 { 1650 struct rk3568_cru *cru = priv->cru; 1651 int src_clk; 1652 1653 switch (rate) { 1654 case OSC_HZ: 1655 src_clk = CCLK_EMMC_SEL_24M; 1656 break; 1657 case 52 * MHz: 1658 case 50 * MHz: 1659 src_clk = CCLK_EMMC_SEL_50M; 1660 break; 1661 case 100 * MHz: 1662 src_clk = CCLK_EMMC_SEL_100M; 1663 break; 1664 case 150 * MHz: 1665 src_clk = CCLK_EMMC_SEL_150M; 1666 break; 1667 case 200 * MHz: 1668 src_clk = CCLK_EMMC_SEL_200M; 1669 break; 1670 case 400 * KHz: 1671 case 375 * KHz: 1672 src_clk = CCLK_EMMC_SEL_375K; 1673 break; 1674 default: 1675 return -ENOENT; 1676 } 1677 1678 rk_clrsetreg(&cru->clksel_con[28], 1679 CCLK_EMMC_SEL_MASK, 1680 src_clk << CCLK_EMMC_SEL_SHIFT); 1681 1682 return rk3568_emmc_get_clk(priv); 1683 } 1684 1685 #ifndef CONFIG_SPL_BUILD 1686 static ulong rk3568_aclk_vop_get_clk(struct rk3568_clk_priv *priv) 1687 { 1688 struct rk3568_cru *cru = priv->cru; 1689 u32 div, sel, con, parent; 1690 1691 con = readl(&cru->clksel_con[38]); 1692 div = (con & ACLK_VOP_PRE_DIV_MASK) >> ACLK_VOP_PRE_DIV_SHIFT; 1693 sel = (con & ACLK_VOP_PRE_SEL_MASK) >> ACLK_VOP_PRE_SEL_SHIFT; 1694 if (sel == ACLK_VOP_PRE_SEL_GPLL) 1695 parent = priv->gpll_hz; 1696 else if (sel == ACLK_VOP_PRE_SEL_CPLL) 1697 parent = priv->cpll_hz; 1698 else if (sel == ACLK_VOP_PRE_SEL_VPLL) 1699 parent = priv->vpll_hz; 1700 else 1701 parent = priv->hpll_hz; 1702 1703 return DIV_TO_RATE(parent, div); 1704 } 1705 1706 static ulong rk3568_aclk_vop_set_clk(struct rk3568_clk_priv *priv, ulong rate) 1707 { 1708 struct rk3568_cru *cru = priv->cru; 1709 int src_clk_div, src_clk_mux; 1710 1711 if ((priv->cpll_hz % rate) == 0) { 1712 src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate); 1713 src_clk_mux = ACLK_VOP_PRE_SEL_CPLL; 1714 } else { 1715 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); 1716 src_clk_mux = ACLK_VOP_PRE_SEL_GPLL; 1717 } 1718 assert(src_clk_div - 1 <= 31); 1719 rk_clrsetreg(&cru->clksel_con[38], 1720 ACLK_VOP_PRE_SEL_MASK | ACLK_VOP_PRE_DIV_MASK, 1721 src_clk_mux << ACLK_VOP_PRE_SEL_SHIFT | 1722 (src_clk_div - 1) << ACLK_VOP_PRE_DIV_SHIFT); 1723 1724 return rk3568_aclk_vop_get_clk(priv); 1725 } 1726 1727 static ulong rk3568_dclk_vop_get_clk(struct rk3568_clk_priv *priv, ulong clk_id) 1728 { 1729 struct rk3568_cru *cru = priv->cru; 1730 u32 conid, div, sel, con, parent; 1731 1732 switch (clk_id) { 1733 case DCLK_VOP0: 1734 conid = 39; 1735 break; 1736 case DCLK_VOP1: 1737 conid = 40; 1738 break; 1739 case DCLK_VOP2: 1740 conid = 41; 1741 break; 1742 default: 1743 return -ENOENT; 1744 } 1745 1746 con = readl(&cru->clksel_con[conid]); 1747 div = (con & DCLK0_VOP_DIV_MASK) >> DCLK0_VOP_DIV_SHIFT; 1748 sel = (con & DCLK0_VOP_SEL_MASK) >> DCLK0_VOP_SEL_SHIFT; 1749 if (sel == DCLK_VOP_SEL_HPLL) 1750 parent = rk3568_pmu_pll_get_rate(priv, HPLL); 1751 else if (sel == DCLK_VOP_SEL_VPLL) 1752 parent = rockchip_pll_get_rate(&rk3568_pll_clks[VPLL], 1753 priv->cru, VPLL); 1754 else if (sel == DCLK_VOP_SEL_GPLL) 1755 parent = priv->gpll_hz; 1756 else if (sel == DCLK_VOP_SEL_CPLL) 1757 parent = priv->cpll_hz; 1758 else 1759 return -ENOENT; 1760 1761 return DIV_TO_RATE(parent, div); 1762 } 1763 1764 #define RK3568_VOP_PLL_LIMIT_FREQ 600000000 1765 1766 static ulong rk3568_dclk_vop_set_clk(struct rk3568_clk_priv *priv, 1767 ulong clk_id, ulong rate) 1768 { 1769 struct rk3568_cru *cru = priv->cru; 1770 ulong pll_rate, now, best_rate = 0; 1771 u32 i, conid, con, sel, div, best_div = 0, best_sel = 0; 1772 1773 switch (clk_id) { 1774 case DCLK_VOP0: 1775 conid = 39; 1776 break; 1777 case DCLK_VOP1: 1778 conid = 40; 1779 break; 1780 case DCLK_VOP2: 1781 conid = 41; 1782 break; 1783 default: 1784 return -ENOENT; 1785 } 1786 1787 con = readl(&cru->clksel_con[conid]); 1788 sel = (con & DCLK0_VOP_SEL_MASK) >> DCLK0_VOP_SEL_SHIFT; 1789 1790 if (sel == DCLK_VOP_SEL_HPLL) { 1791 div = 1; 1792 rk_clrsetreg(&cru->clksel_con[conid], 1793 DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK, 1794 (DCLK_VOP_SEL_HPLL << DCLK0_VOP_SEL_SHIFT) | 1795 ((div - 1) << DCLK0_VOP_DIV_SHIFT)); 1796 rk3568_pmu_pll_set_rate(priv, HPLL, div * rate); 1797 } else if (sel == DCLK_VOP_SEL_VPLL) { 1798 div = DIV_ROUND_UP(RK3568_VOP_PLL_LIMIT_FREQ, rate); 1799 rk_clrsetreg(&cru->clksel_con[conid], 1800 DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK, 1801 (DCLK_VOP_SEL_VPLL << DCLK0_VOP_SEL_SHIFT) | 1802 ((div - 1) << DCLK0_VOP_DIV_SHIFT)); 1803 rockchip_pll_set_rate(&rk3568_pll_clks[VPLL], 1804 priv->cru, VPLL, div * rate); 1805 } else { 1806 for (i = 0; i <= DCLK_VOP_SEL_CPLL; i++) { 1807 switch (i) { 1808 case DCLK_VOP_SEL_GPLL: 1809 pll_rate = priv->gpll_hz; 1810 break; 1811 case DCLK_VOP_SEL_CPLL: 1812 pll_rate = priv->cpll_hz; 1813 break; 1814 default: 1815 printf("do not support this vop pll sel\n"); 1816 return -EINVAL; 1817 } 1818 1819 div = DIV_ROUND_UP(pll_rate, rate); 1820 if (div > 255) 1821 continue; 1822 now = pll_rate / div; 1823 if (abs(rate - now) < abs(rate - best_rate)) { 1824 best_rate = now; 1825 best_div = div; 1826 best_sel = i; 1827 } 1828 debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n", 1829 pll_rate, best_rate, best_div, best_sel); 1830 } 1831 1832 if (best_rate) { 1833 rk_clrsetreg(&cru->clksel_con[conid], 1834 DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK, 1835 best_sel << DCLK0_VOP_SEL_SHIFT | 1836 (best_div - 1) << DCLK0_VOP_DIV_SHIFT); 1837 } else { 1838 printf("do not support this vop freq %lu\n", rate); 1839 return -EINVAL; 1840 } 1841 } 1842 return rk3568_dclk_vop_get_clk(priv, clk_id); 1843 } 1844 1845 static ulong rk3568_gmac_src_get_clk(struct rk3568_clk_priv *priv, 1846 ulong mac_id) 1847 { 1848 struct rk3568_cru *cru = priv->cru; 1849 u32 sel, con; 1850 1851 con = readl(&cru->clksel_con[31 + mac_id * 2]); 1852 sel = (con & CLK_MAC0_2TOP_SEL_MASK) >> CLK_MAC0_2TOP_SEL_SHIFT; 1853 1854 switch (sel) { 1855 case CLK_MAC0_2TOP_SEL_125M: 1856 return 125 * MHz; 1857 case CLK_MAC0_2TOP_SEL_50M: 1858 return 50 * MHz; 1859 case CLK_MAC0_2TOP_SEL_25M: 1860 return 25 * MHz; 1861 case CLK_MAC0_2TOP_SEL_PPLL: 1862 return rk3568_pmu_pll_get_rate(priv, HPLL); 1863 default: 1864 return -ENOENT; 1865 } 1866 } 1867 1868 static ulong rk3568_gmac_src_set_clk(struct rk3568_clk_priv *priv, 1869 ulong mac_id, ulong rate) 1870 { 1871 struct rk3568_cru *cru = priv->cru; 1872 int src_clk; 1873 1874 switch (rate) { 1875 case 125 * MHz: 1876 src_clk = CLK_MAC0_2TOP_SEL_125M; 1877 break; 1878 case 50 * MHz: 1879 src_clk = CLK_MAC0_2TOP_SEL_50M; 1880 break; 1881 case 25 * MHz: 1882 src_clk = CLK_MAC0_2TOP_SEL_25M; 1883 break; 1884 default: 1885 return -ENOENT; 1886 } 1887 1888 rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2], 1889 CLK_MAC0_2TOP_SEL_MASK, 1890 src_clk << CLK_MAC0_2TOP_SEL_SHIFT); 1891 1892 return rk3568_gmac_src_get_clk(priv, mac_id); 1893 } 1894 1895 static ulong rk3568_gmac_out_get_clk(struct rk3568_clk_priv *priv, 1896 ulong mac_id) 1897 { 1898 struct rk3568_cru *cru = priv->cru; 1899 u32 sel, con; 1900 1901 con = readl(&cru->clksel_con[31 + mac_id * 2]); 1902 sel = (con & CLK_MAC0_OUT_SEL_MASK) >> CLK_MAC0_OUT_SEL_SHIFT; 1903 1904 switch (sel) { 1905 case CLK_MAC0_OUT_SEL_125M: 1906 return 125 * MHz; 1907 case CLK_MAC0_OUT_SEL_50M: 1908 return 50 * MHz; 1909 case CLK_MAC0_OUT_SEL_25M: 1910 return 25 * MHz; 1911 case CLK_MAC0_OUT_SEL_24M: 1912 return OSC_HZ; 1913 default: 1914 return -ENOENT; 1915 } 1916 } 1917 1918 static ulong rk3568_gmac_out_set_clk(struct rk3568_clk_priv *priv, 1919 ulong mac_id, ulong rate) 1920 { 1921 struct rk3568_cru *cru = priv->cru; 1922 int src_clk; 1923 1924 switch (rate) { 1925 case 125 * MHz: 1926 src_clk = CLK_MAC0_OUT_SEL_125M; 1927 break; 1928 case 50 * MHz: 1929 src_clk = CLK_MAC0_OUT_SEL_50M; 1930 break; 1931 case 25 * MHz: 1932 src_clk = CLK_MAC0_OUT_SEL_25M; 1933 break; 1934 case 24 * MHz: 1935 src_clk = CLK_MAC0_OUT_SEL_24M; 1936 break; 1937 default: 1938 return -ENOENT; 1939 } 1940 1941 rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2], 1942 CLK_MAC0_OUT_SEL_MASK, 1943 src_clk << CLK_MAC0_OUT_SEL_SHIFT); 1944 1945 return rk3568_gmac_out_get_clk(priv, mac_id); 1946 } 1947 1948 static ulong rk3568_gmac_ptp_ref_get_clk(struct rk3568_clk_priv *priv, 1949 ulong mac_id) 1950 { 1951 struct rk3568_cru *cru = priv->cru; 1952 u32 sel, con; 1953 1954 con = readl(&cru->clksel_con[31 + mac_id * 2]); 1955 sel = (con & CLK_GMAC0_PTP_REF_SEL_MASK) >> CLK_GMAC0_PTP_REF_SEL_SHIFT; 1956 1957 switch (sel) { 1958 case CLK_GMAC0_PTP_REF_SEL_62_5M: 1959 return 62500 * KHz; 1960 case CLK_GMAC0_PTP_REF_SEL_100M: 1961 return 100 * MHz; 1962 case CLK_GMAC0_PTP_REF_SEL_50M: 1963 return 50 * MHz; 1964 case CLK_GMAC0_PTP_REF_SEL_24M: 1965 return OSC_HZ; 1966 default: 1967 return -ENOENT; 1968 } 1969 } 1970 1971 static ulong rk3568_gmac_ptp_ref_set_clk(struct rk3568_clk_priv *priv, 1972 ulong mac_id, ulong rate) 1973 { 1974 struct rk3568_cru *cru = priv->cru; 1975 int src_clk; 1976 1977 switch (rate) { 1978 case 62500 * KHz: 1979 src_clk = CLK_GMAC0_PTP_REF_SEL_62_5M; 1980 break; 1981 case 100 * MHz: 1982 src_clk = CLK_GMAC0_PTP_REF_SEL_100M; 1983 break; 1984 case 50 * MHz: 1985 src_clk = CLK_GMAC0_PTP_REF_SEL_50M; 1986 break; 1987 case 24 * MHz: 1988 src_clk = CLK_GMAC0_PTP_REF_SEL_24M; 1989 break; 1990 default: 1991 return -ENOENT; 1992 } 1993 1994 rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2], 1995 CLK_GMAC0_PTP_REF_SEL_MASK, 1996 src_clk << CLK_GMAC0_PTP_REF_SEL_SHIFT); 1997 1998 return rk3568_gmac_ptp_ref_get_clk(priv, mac_id); 1999 } 2000 2001 static ulong rk3568_gmac_tx_rx_set_clk(struct rk3568_clk_priv *priv, 2002 ulong mac_id, ulong rate) 2003 { 2004 struct rk3568_cru *cru = priv->cru; 2005 u32 con, sel, div_sel; 2006 2007 con = readl(&cru->clksel_con[31 + mac_id * 2]); 2008 sel = (con & RMII0_MODE_MASK) >> RMII0_MODE_SHIFT; 2009 2010 if (sel == RMII0_MODE_SEL_RGMII) { 2011 if (rate == 2500000) 2012 div_sel = RGMII0_CLK_SEL_2_5M; 2013 else if (rate == 25000000) 2014 div_sel = RGMII0_CLK_SEL_25M; 2015 else 2016 div_sel = RGMII0_CLK_SEL_125M; 2017 rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2], 2018 RGMII0_CLK_SEL_MASK, 2019 div_sel << RGMII0_CLK_SEL_SHIFT); 2020 } else if (sel == RMII0_MODE_SEL_RMII) { 2021 if (rate == 2500000) 2022 div_sel = RMII0_CLK_SEL_2_5M; 2023 else 2024 div_sel = RMII0_CLK_SEL_25M; 2025 rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2], 2026 RMII0_CLK_SEL_MASK, 2027 div_sel << RMII0_CLK_SEL_SHIFT); 2028 } 2029 2030 return 0; 2031 } 2032 2033 static ulong rk3568_ebc_get_clk(struct rk3568_clk_priv *priv) 2034 { 2035 struct rk3568_cru *cru = priv->cru; 2036 u32 con, div, p_rate; 2037 2038 con = readl(&cru->clksel_con[79]); 2039 div = (con & CPLL_333M_DIV_MASK) >> CPLL_333M_DIV_SHIFT; 2040 p_rate = DIV_TO_RATE(priv->cpll_hz, div); 2041 2042 con = readl(&cru->clksel_con[43]); 2043 div = (con & DCLK_EBC_SEL_MASK) >> DCLK_EBC_SEL_SHIFT; 2044 switch (div) { 2045 case DCLK_EBC_SEL_GPLL_400M: 2046 return 400 * MHz; 2047 case DCLK_EBC_SEL_CPLL_333M: 2048 return p_rate; 2049 case DCLK_EBC_SEL_GPLL_200M: 2050 return 200 * MHz; 2051 default: 2052 return -ENOENT; 2053 } 2054 } 2055 2056 static ulong rk3568_ebc_set_clk(struct rk3568_clk_priv *priv, ulong rate) 2057 { 2058 struct rk3568_cru *cru = priv->cru; 2059 int src_clk_div; 2060 2061 src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate); 2062 assert(src_clk_div - 1 <= 31); 2063 rk_clrsetreg(&cru->clksel_con[79], 2064 CPLL_333M_DIV_MASK, 2065 (src_clk_div - 1) << CPLL_333M_DIV_SHIFT); 2066 rk_clrsetreg(&cru->clksel_con[43], 2067 DCLK_EBC_SEL_MASK, 2068 DCLK_EBC_SEL_CPLL_333M << DCLK_EBC_SEL_SHIFT); 2069 2070 return rk3568_ebc_get_clk(priv); 2071 } 2072 2073 static ulong rk3568_rkvdec_get_clk(struct rk3568_clk_priv *priv, ulong clk_id) 2074 { 2075 struct rk3568_cru *cru = priv->cru; 2076 u32 con, div, src, p_rate; 2077 2078 switch (clk_id) { 2079 case ACLK_RKVDEC_PRE: 2080 case ACLK_RKVDEC: 2081 con = readl(&cru->clksel_con[47]); 2082 src = (con & ACLK_RKVDEC_SEL_MASK) >> ACLK_RKVDEC_SEL_SHIFT; 2083 div = (con & ACLK_RKVDEC_DIV_MASK) >> ACLK_RKVDEC_DIV_SHIFT; 2084 if (src == ACLK_RKVDEC_SEL_CPLL) 2085 p_rate = priv->cpll_hz; 2086 else 2087 p_rate = priv->gpll_hz; 2088 return DIV_TO_RATE(p_rate, div); 2089 case CLK_RKVDEC_CORE: 2090 con = readl(&cru->clksel_con[49]); 2091 src = (con & CLK_RKVDEC_CORE_SEL_MASK) 2092 >> CLK_RKVDEC_CORE_SEL_SHIFT; 2093 div = (con & CLK_RKVDEC_CORE_DIV_MASK) 2094 >> CLK_RKVDEC_CORE_DIV_SHIFT; 2095 if (src == CLK_RKVDEC_CORE_SEL_CPLL) 2096 p_rate = priv->cpll_hz; 2097 else if (src == CLK_RKVDEC_CORE_SEL_NPLL) 2098 p_rate = priv->npll_hz; 2099 else if (src == CLK_RKVDEC_CORE_SEL_VPLL) 2100 p_rate = priv->vpll_hz; 2101 else 2102 p_rate = priv->gpll_hz; 2103 return DIV_TO_RATE(p_rate, div); 2104 default: 2105 return -ENOENT; 2106 } 2107 } 2108 2109 static ulong rk3568_rkvdec_set_clk(struct rk3568_clk_priv *priv, 2110 ulong clk_id, ulong rate) 2111 { 2112 struct rk3568_cru *cru = priv->cru; 2113 int src_clk_div, src, p_rate; 2114 2115 switch (clk_id) { 2116 case ACLK_RKVDEC_PRE: 2117 case ACLK_RKVDEC: 2118 src = (readl(&cru->clksel_con[47]) & ACLK_RKVDEC_SEL_MASK) 2119 >> ACLK_RKVDEC_SEL_SHIFT; 2120 if (src == ACLK_RKVDEC_SEL_CPLL) 2121 p_rate = priv->cpll_hz; 2122 else 2123 p_rate = priv->gpll_hz; 2124 src_clk_div = DIV_ROUND_UP(p_rate, rate); 2125 assert(src_clk_div - 1 <= 31); 2126 rk_clrsetreg(&cru->clksel_con[47], 2127 ACLK_RKVDEC_SEL_MASK | 2128 ACLK_RKVDEC_DIV_MASK, 2129 (src << ACLK_RKVDEC_SEL_SHIFT) | 2130 (src_clk_div - 1) << ACLK_RKVDEC_DIV_SHIFT); 2131 break; 2132 case CLK_RKVDEC_CORE: 2133 src = (readl(&cru->clksel_con[49]) & CLK_RKVDEC_CORE_SEL_MASK) 2134 >> CLK_RKVDEC_CORE_SEL_SHIFT; 2135 if (src == CLK_RKVDEC_CORE_SEL_CPLL) 2136 p_rate = priv->cpll_hz; 2137 else if (src == CLK_RKVDEC_CORE_SEL_NPLL) 2138 p_rate = priv->npll_hz; 2139 else if (src == CLK_RKVDEC_CORE_SEL_VPLL) 2140 p_rate = priv->vpll_hz; 2141 else 2142 p_rate = priv->gpll_hz; 2143 src_clk_div = DIV_ROUND_UP(p_rate, rate); 2144 assert(src_clk_div - 1 <= 31); 2145 rk_clrsetreg(&cru->clksel_con[49], 2146 CLK_RKVDEC_CORE_SEL_MASK | 2147 CLK_RKVDEC_CORE_DIV_MASK, 2148 (src << CLK_RKVDEC_CORE_SEL_SHIFT) | 2149 (src_clk_div - 1) << CLK_RKVDEC_CORE_DIV_SHIFT); 2150 break; 2151 default: 2152 return -ENOENT; 2153 } 2154 2155 return rk3568_rkvdec_get_clk(priv, clk_id); 2156 } 2157 #endif 2158 2159 static ulong rk3568_clk_get_rate(struct clk *clk) 2160 { 2161 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev); 2162 ulong rate = 0; 2163 2164 if (!priv->gpll_hz) { 2165 printf("%s gpll=%lu\n", __func__, priv->gpll_hz); 2166 return -ENOENT; 2167 } 2168 2169 switch (clk->id) { 2170 case PLL_APLL: 2171 case ARMCLK: 2172 rate = rockchip_pll_get_rate(&rk3568_pll_clks[APLL], priv->cru, 2173 APLL); 2174 break; 2175 case PLL_CPLL: 2176 rate = rockchip_pll_get_rate(&rk3568_pll_clks[CPLL], priv->cru, 2177 CPLL); 2178 break; 2179 case PLL_GPLL: 2180 rate = rockchip_pll_get_rate(&rk3568_pll_clks[GPLL], priv->cru, 2181 GPLL); 2182 break; 2183 case PLL_NPLL: 2184 rate = rockchip_pll_get_rate(&rk3568_pll_clks[NPLL], priv->cru, 2185 NPLL); 2186 break; 2187 case PLL_VPLL: 2188 rate = rockchip_pll_get_rate(&rk3568_pll_clks[VPLL], priv->cru, 2189 VPLL); 2190 break; 2191 case PLL_DPLL: 2192 rate = rockchip_pll_get_rate(&rk3568_pll_clks[DPLL], priv->cru, 2193 DPLL); 2194 break; 2195 case ACLK_BUS: 2196 case PCLK_BUS: 2197 case PCLK_WDT_NS: 2198 rate = rk3568_bus_get_clk(priv, clk->id); 2199 break; 2200 case ACLK_PERIMID: 2201 case HCLK_PERIMID: 2202 rate = rk3568_perimid_get_clk(priv, clk->id); 2203 break; 2204 case ACLK_TOP_HIGH: 2205 case ACLK_TOP_LOW: 2206 case HCLK_TOP: 2207 case PCLK_TOP: 2208 rate = rk3568_top_get_clk(priv, clk->id); 2209 break; 2210 case CLK_I2C1: 2211 case CLK_I2C2: 2212 case CLK_I2C3: 2213 case CLK_I2C4: 2214 case CLK_I2C5: 2215 rate = rk3568_i2c_get_clk(priv, clk->id); 2216 break; 2217 case CLK_SPI0: 2218 case CLK_SPI1: 2219 case CLK_SPI2: 2220 case CLK_SPI3: 2221 rate = rk3568_spi_get_clk(priv, clk->id); 2222 break; 2223 case CLK_PWM1: 2224 case CLK_PWM2: 2225 case CLK_PWM3: 2226 rate = rk3568_pwm_get_clk(priv, clk->id); 2227 break; 2228 case CLK_SARADC: 2229 case CLK_TSADC_TSEN: 2230 case CLK_TSADC: 2231 rate = rk3568_adc_get_clk(priv, clk->id); 2232 break; 2233 case HCLK_SDMMC0: 2234 case CLK_SDMMC0: 2235 case CLK_SDMMC1: 2236 case CLK_SDMMC2: 2237 rate = rk3568_sdmmc_get_clk(priv, clk->id); 2238 break; 2239 case SCLK_SFC: 2240 rate = rk3568_sfc_get_clk(priv); 2241 break; 2242 case NCLK_NANDC: 2243 rate = rk3568_nand_get_clk(priv); 2244 break; 2245 case CCLK_EMMC: 2246 rate = rk3568_emmc_get_clk(priv); 2247 break; 2248 #ifndef CONFIG_SPL_BUILD 2249 case ACLK_VOP: 2250 rate = rk3568_aclk_vop_get_clk(priv); 2251 break; 2252 case DCLK_VOP0: 2253 case DCLK_VOP1: 2254 case DCLK_VOP2: 2255 rate = rk3568_dclk_vop_get_clk(priv, clk->id); 2256 break; 2257 case SCLK_GMAC0: 2258 case CLK_MAC0_2TOP: 2259 case CLK_MAC0_REFOUT: 2260 rate = rk3568_gmac_src_get_clk(priv, 0); 2261 break; 2262 case CLK_MAC0_OUT: 2263 rate = rk3568_gmac_out_get_clk(priv, 0); 2264 break; 2265 case CLK_GMAC0_PTP_REF: 2266 rate = rk3568_gmac_ptp_ref_get_clk(priv, 0); 2267 break; 2268 case SCLK_GMAC1: 2269 case CLK_MAC1_2TOP: 2270 case CLK_MAC1_REFOUT: 2271 rate = rk3568_gmac_src_get_clk(priv, 1); 2272 break; 2273 case CLK_MAC1_OUT: 2274 rate = rk3568_gmac_out_get_clk(priv, 1); 2275 break; 2276 case CLK_GMAC1_PTP_REF: 2277 rate = rk3568_gmac_ptp_ref_get_clk(priv, 1); 2278 break; 2279 case DCLK_EBC: 2280 rate = rk3568_ebc_get_clk(priv); 2281 break; 2282 case ACLK_RKVDEC_PRE: 2283 case ACLK_RKVDEC: 2284 case CLK_RKVDEC_CORE: 2285 rate = rk3568_rkvdec_get_clk(priv, clk->id); 2286 break; 2287 case TCLK_WDT_NS: 2288 rate = OSC_HZ; 2289 break; 2290 #endif 2291 case ACLK_SECURE_FLASH: 2292 case ACLK_CRYPTO_NS: 2293 case HCLK_SECURE_FLASH: 2294 case HCLK_CRYPTO_NS: 2295 case CLK_CRYPTO_NS_RNG: 2296 case CLK_CRYPTO_NS_CORE: 2297 case CLK_CRYPTO_NS_PKA: 2298 rate = rk3568_crypto_get_rate(priv, clk->id); 2299 break; 2300 case CPLL_500M: 2301 case CPLL_333M: 2302 case CPLL_250M: 2303 case CPLL_125M: 2304 case CPLL_100M: 2305 case CPLL_62P5M: 2306 case CPLL_50M: 2307 case CPLL_25M: 2308 rate = rk3568_cpll_div_get_rate(priv, clk->id); 2309 break; 2310 default: 2311 return -ENOENT; 2312 } 2313 2314 return rate; 2315 }; 2316 2317 static ulong rk3568_clk_set_rate(struct clk *clk, ulong rate) 2318 { 2319 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev); 2320 ulong ret = 0; 2321 2322 if (!priv->gpll_hz) { 2323 printf("%s gpll=%lu\n", __func__, priv->gpll_hz); 2324 return -ENOENT; 2325 } 2326 2327 switch (clk->id) { 2328 case PLL_APLL: 2329 case ARMCLK: 2330 if (priv->armclk_hz) 2331 rk3568_armclk_set_clk(priv, rate); 2332 priv->armclk_hz = rate; 2333 break; 2334 case PLL_CPLL: 2335 ret = rockchip_pll_set_rate(&rk3568_pll_clks[CPLL], priv->cru, 2336 CPLL, rate); 2337 priv->cpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[CPLL], 2338 priv->cru, CPLL); 2339 break; 2340 case PLL_GPLL: 2341 ret = rockchip_pll_set_rate(&rk3568_pll_clks[GPLL], priv->cru, 2342 GPLL, rate); 2343 priv->gpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[GPLL], 2344 priv->cru, GPLL); 2345 break; 2346 case PLL_NPLL: 2347 ret = rockchip_pll_set_rate(&rk3568_pll_clks[NPLL], priv->cru, 2348 NPLL, rate); 2349 break; 2350 case PLL_VPLL: 2351 ret = rockchip_pll_set_rate(&rk3568_pll_clks[VPLL], priv->cru, 2352 VPLL, rate); 2353 priv->vpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[VPLL], 2354 priv->cru, 2355 VPLL); 2356 break; 2357 case ACLK_BUS: 2358 case PCLK_BUS: 2359 case PCLK_WDT_NS: 2360 ret = rk3568_bus_set_clk(priv, clk->id, rate); 2361 break; 2362 case ACLK_PERIMID: 2363 case HCLK_PERIMID: 2364 ret = rk3568_perimid_set_clk(priv, clk->id, rate); 2365 break; 2366 case ACLK_TOP_HIGH: 2367 case ACLK_TOP_LOW: 2368 case HCLK_TOP: 2369 case PCLK_TOP: 2370 ret = rk3568_top_set_clk(priv, clk->id, rate); 2371 break; 2372 case CLK_I2C1: 2373 case CLK_I2C2: 2374 case CLK_I2C3: 2375 case CLK_I2C4: 2376 case CLK_I2C5: 2377 ret = rk3568_i2c_set_clk(priv, clk->id, rate); 2378 break; 2379 case CLK_SPI0: 2380 case CLK_SPI1: 2381 case CLK_SPI2: 2382 case CLK_SPI3: 2383 ret = rk3568_spi_set_clk(priv, clk->id, rate); 2384 break; 2385 case CLK_PWM1: 2386 case CLK_PWM2: 2387 case CLK_PWM3: 2388 ret = rk3568_pwm_set_clk(priv, clk->id, rate); 2389 break; 2390 case CLK_SARADC: 2391 case CLK_TSADC_TSEN: 2392 case CLK_TSADC: 2393 ret = rk3568_adc_set_clk(priv, clk->id, rate); 2394 break; 2395 case HCLK_SDMMC0: 2396 case CLK_SDMMC0: 2397 case CLK_SDMMC1: 2398 case CLK_SDMMC2: 2399 ret = rk3568_sdmmc_set_clk(priv, clk->id, rate); 2400 break; 2401 case SCLK_SFC: 2402 ret = rk3568_sfc_set_clk(priv, rate); 2403 break; 2404 case NCLK_NANDC: 2405 ret = rk3568_nand_set_clk(priv, rate); 2406 break; 2407 case CCLK_EMMC: 2408 ret = rk3568_emmc_set_clk(priv, rate); 2409 break; 2410 #ifndef CONFIG_SPL_BUILD 2411 case ACLK_VOP: 2412 ret = rk3568_aclk_vop_set_clk(priv, rate); 2413 break; 2414 case DCLK_VOP0: 2415 case DCLK_VOP1: 2416 case DCLK_VOP2: 2417 ret = rk3568_dclk_vop_set_clk(priv, clk->id, rate); 2418 break; 2419 case SCLK_GMAC0: 2420 case CLK_MAC0_2TOP: 2421 case CLK_MAC0_REFOUT: 2422 ret = rk3568_gmac_src_set_clk(priv, 0, rate); 2423 break; 2424 case CLK_MAC0_OUT: 2425 ret = rk3568_gmac_out_set_clk(priv, 0, rate); 2426 break; 2427 case SCLK_GMAC0_RX_TX: 2428 ret = rk3568_gmac_tx_rx_set_clk(priv, 0, rate); 2429 break; 2430 case CLK_GMAC0_PTP_REF: 2431 ret = rk3568_gmac_ptp_ref_set_clk(priv, 0, rate); 2432 break; 2433 case SCLK_GMAC1: 2434 case CLK_MAC1_2TOP: 2435 case CLK_MAC1_REFOUT: 2436 ret = rk3568_gmac_src_set_clk(priv, 1, rate); 2437 break; 2438 case CLK_MAC1_OUT: 2439 ret = rk3568_gmac_out_set_clk(priv, 1, rate); 2440 break; 2441 case SCLK_GMAC1_RX_TX: 2442 ret = rk3568_gmac_tx_rx_set_clk(priv, 1, rate); 2443 break; 2444 case CLK_GMAC1_PTP_REF: 2445 ret = rk3568_gmac_ptp_ref_set_clk(priv, 1, rate); 2446 break; 2447 case DCLK_EBC: 2448 ret = rk3568_ebc_set_clk(priv, rate); 2449 break; 2450 case ACLK_RKVDEC_PRE: 2451 case ACLK_RKVDEC: 2452 case CLK_RKVDEC_CORE: 2453 ret = rk3568_rkvdec_set_clk(priv, clk->id, rate); 2454 break; 2455 case TCLK_WDT_NS: 2456 ret = OSC_HZ; 2457 break; 2458 #endif 2459 case ACLK_SECURE_FLASH: 2460 case ACLK_CRYPTO_NS: 2461 case HCLK_SECURE_FLASH: 2462 case HCLK_CRYPTO_NS: 2463 case CLK_CRYPTO_NS_RNG: 2464 case CLK_CRYPTO_NS_CORE: 2465 case CLK_CRYPTO_NS_PKA: 2466 ret = rk3568_crypto_set_rate(priv, clk->id, rate); 2467 break; 2468 case CPLL_500M: 2469 case CPLL_333M: 2470 case CPLL_250M: 2471 case CPLL_125M: 2472 case CPLL_100M: 2473 case CPLL_62P5M: 2474 case CPLL_50M: 2475 case CPLL_25M: 2476 ret = rk3568_cpll_div_set_rate(priv, clk->id, rate); 2477 break; 2478 default: 2479 return -ENOENT; 2480 } 2481 2482 return ret; 2483 }; 2484 2485 #define ROCKCHIP_MMC_DELAY_SEL BIT(10) 2486 #define ROCKCHIP_MMC_DEGREE_MASK 0x3 2487 #define ROCKCHIP_MMC_DELAYNUM_OFFSET 2 2488 #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET) 2489 2490 #define PSECS_PER_SEC 1000000000000LL 2491 /* 2492 * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to 2493 * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg. 2494 */ 2495 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60 2496 2497 int rk3568_mmc_get_phase(struct clk *clk) 2498 { 2499 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev); 2500 struct rk3568_cru *cru = priv->cru; 2501 u32 raw_value, delay_num; 2502 u16 degrees = 0; 2503 ulong rate; 2504 2505 rate = rk3568_clk_get_rate(clk); 2506 if (rate < 0) 2507 return rate; 2508 2509 if (clk->id == SCLK_EMMC_SAMPLE) 2510 raw_value = readl(&cru->emmc_con[1]); 2511 else if (clk->id == SCLK_SDMMC0_SAMPLE) 2512 raw_value = readl(&cru->sdmmc0_con[1]); 2513 else if (clk->id == SCLK_SDMMC1_SAMPLE) 2514 raw_value = readl(&cru->sdmmc1_con[1]); 2515 else 2516 raw_value = readl(&cru->sdmmc2_con[1]); 2517 2518 raw_value >>= 1; 2519 degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90; 2520 2521 if (raw_value & ROCKCHIP_MMC_DELAY_SEL) { 2522 /* degrees/delaynum * 10000 */ 2523 unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) * 2524 36 * (rate / 1000000); 2525 2526 delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK); 2527 delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET; 2528 degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000); 2529 } 2530 2531 return degrees % 360; 2532 } 2533 2534 int rk3568_mmc_set_phase(struct clk *clk, u32 degrees) 2535 { 2536 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev); 2537 struct rk3568_cru *cru = priv->cru; 2538 u8 nineties, remainder, delay_num; 2539 u32 raw_value, delay; 2540 ulong rate; 2541 2542 rate = rk3568_clk_get_rate(clk); 2543 if (rate < 0) 2544 return rate; 2545 2546 nineties = degrees / 90; 2547 remainder = (degrees % 90); 2548 2549 /* 2550 * Convert to delay; do a little extra work to make sure we 2551 * don't overflow 32-bit / 64-bit numbers. 2552 */ 2553 delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */ 2554 delay *= remainder; 2555 delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 * 2556 (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10)); 2557 2558 delay_num = (u8)min_t(u32, delay, 255); 2559 2560 raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0; 2561 raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET; 2562 raw_value |= nineties; 2563 2564 raw_value <<= 1; 2565 if (clk->id == SCLK_EMMC_SAMPLE) 2566 writel(raw_value | 0xffff0000, &cru->emmc_con[1]); 2567 else if (clk->id == SCLK_SDMMC0_SAMPLE) 2568 writel(raw_value | 0xffff0000, &cru->sdmmc0_con[1]); 2569 else if (clk->id == SCLK_SDMMC1_SAMPLE) 2570 writel(raw_value | 0xffff0000, &cru->sdmmc1_con[1]); 2571 else 2572 writel(raw_value | 0xffff0000, &cru->sdmmc2_con[1]); 2573 2574 debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n", 2575 degrees, delay_num, raw_value, rk3568_mmc_get_phase(clk)); 2576 2577 return 0; 2578 } 2579 2580 static int rk3568_clk_get_phase(struct clk *clk) 2581 { 2582 int ret; 2583 2584 debug("%s %ld\n", __func__, clk->id); 2585 switch (clk->id) { 2586 case SCLK_EMMC_SAMPLE: 2587 case SCLK_SDMMC0_SAMPLE: 2588 case SCLK_SDMMC1_SAMPLE: 2589 case SCLK_SDMMC2_SAMPLE: 2590 ret = rk3568_mmc_get_phase(clk); 2591 break; 2592 default: 2593 return -ENOENT; 2594 } 2595 2596 return ret; 2597 } 2598 2599 static int rk3568_clk_set_phase(struct clk *clk, int degrees) 2600 { 2601 int ret; 2602 2603 debug("%s %ld\n", __func__, clk->id); 2604 switch (clk->id) { 2605 case SCLK_EMMC_SAMPLE: 2606 case SCLK_SDMMC0_SAMPLE: 2607 case SCLK_SDMMC1_SAMPLE: 2608 case SCLK_SDMMC2_SAMPLE: 2609 ret = rk3568_mmc_set_phase(clk, degrees); 2610 break; 2611 default: 2612 return -ENOENT; 2613 } 2614 2615 return ret; 2616 } 2617 2618 #if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA)) 2619 static int rk3568_gmac0_src_set_parent(struct clk *clk, struct clk *parent) 2620 { 2621 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev); 2622 struct rk3568_cru *cru = priv->cru; 2623 2624 if (parent->id == CLK_MAC0_2TOP) 2625 rk_clrsetreg(&cru->clksel_con[31], 2626 RMII0_EXTCLK_SEL_MASK, 2627 RMII0_EXTCLK_SEL_MAC0_TOP << 2628 RMII0_EXTCLK_SEL_SHIFT); 2629 else 2630 rk_clrsetreg(&cru->clksel_con[31], 2631 RMII0_EXTCLK_SEL_MASK, 2632 RMII0_EXTCLK_SEL_IO << RMII0_EXTCLK_SEL_SHIFT); 2633 return 0; 2634 } 2635 2636 static int rk3568_gmac1_src_set_parent(struct clk *clk, struct clk *parent) 2637 { 2638 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev); 2639 struct rk3568_cru *cru = priv->cru; 2640 2641 if (parent->id == CLK_MAC1_2TOP) 2642 rk_clrsetreg(&cru->clksel_con[33], 2643 RMII0_EXTCLK_SEL_MASK, 2644 RMII0_EXTCLK_SEL_MAC0_TOP << 2645 RMII0_EXTCLK_SEL_SHIFT); 2646 else 2647 rk_clrsetreg(&cru->clksel_con[33], 2648 RMII0_EXTCLK_SEL_MASK, 2649 RMII0_EXTCLK_SEL_IO << RMII0_EXTCLK_SEL_SHIFT); 2650 return 0; 2651 } 2652 2653 static int rk3568_gmac0_tx_rx_set_parent(struct clk *clk, struct clk *parent) 2654 { 2655 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev); 2656 struct rk3568_cru *cru = priv->cru; 2657 2658 if (parent->id == SCLK_GMAC0_RGMII_SPEED) 2659 rk_clrsetreg(&cru->clksel_con[31], 2660 RMII0_MODE_MASK, 2661 RMII0_MODE_SEL_RGMII << RMII0_MODE_SHIFT); 2662 else if (parent->id == SCLK_GMAC0_RMII_SPEED) 2663 rk_clrsetreg(&cru->clksel_con[31], 2664 RMII0_MODE_MASK, 2665 RMII0_MODE_SEL_RMII << RMII0_MODE_SHIFT); 2666 else 2667 rk_clrsetreg(&cru->clksel_con[31], 2668 RMII0_MODE_MASK, 2669 RMII0_MODE_SEL_GMII << RMII0_MODE_SHIFT); 2670 2671 return 0; 2672 } 2673 2674 static int rk3568_gmac1_tx_rx_set_parent(struct clk *clk, struct clk *parent) 2675 { 2676 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev); 2677 struct rk3568_cru *cru = priv->cru; 2678 2679 if (parent->id == SCLK_GMAC1_RGMII_SPEED) 2680 rk_clrsetreg(&cru->clksel_con[33], 2681 RMII0_MODE_MASK, 2682 RMII0_MODE_SEL_RGMII << RMII0_MODE_SHIFT); 2683 else if (parent->id == SCLK_GMAC1_RMII_SPEED) 2684 rk_clrsetreg(&cru->clksel_con[33], 2685 RMII0_MODE_MASK, 2686 RMII0_MODE_SEL_RMII << RMII0_MODE_SHIFT); 2687 else 2688 rk_clrsetreg(&cru->clksel_con[33], 2689 RMII0_MODE_MASK, 2690 RMII0_MODE_SEL_GMII << RMII0_MODE_SHIFT); 2691 2692 return 0; 2693 } 2694 2695 static int __maybe_unused rk3568_dclk_vop_set_parent(struct clk *clk, 2696 struct clk *parent) 2697 { 2698 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev); 2699 struct rk3568_cru *cru = priv->cru; 2700 u32 con_id; 2701 2702 switch (clk->id) { 2703 case DCLK_VOP0: 2704 con_id = 39; 2705 break; 2706 case DCLK_VOP1: 2707 con_id = 40; 2708 break; 2709 case DCLK_VOP2: 2710 con_id = 41; 2711 break; 2712 default: 2713 return -EINVAL; 2714 } 2715 if (parent->id == PLL_VPLL) { 2716 rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK, 2717 DCLK_VOP_SEL_VPLL << DCLK0_VOP_SEL_SHIFT); 2718 } else { 2719 rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK, 2720 DCLK_VOP_SEL_HPLL << DCLK0_VOP_SEL_SHIFT); 2721 } 2722 2723 return 0; 2724 } 2725 2726 static int __maybe_unused rk3568_rkvdec_set_parent(struct clk *clk, 2727 struct clk *parent) 2728 { 2729 struct rk3568_clk_priv *priv = dev_get_priv(clk->dev); 2730 struct rk3568_cru *cru = priv->cru; 2731 u32 con_id, mask, shift; 2732 2733 switch (clk->id) { 2734 case ACLK_RKVDEC_PRE: 2735 con_id = 47; 2736 mask = ACLK_RKVDEC_SEL_MASK; 2737 shift = ACLK_RKVDEC_SEL_SHIFT; 2738 break; 2739 case CLK_RKVDEC_CORE: 2740 con_id = 49; 2741 mask = CLK_RKVDEC_CORE_SEL_MASK; 2742 shift = CLK_RKVDEC_CORE_SEL_SHIFT; 2743 break; 2744 default: 2745 return -EINVAL; 2746 } 2747 if (parent->id == PLL_CPLL) { 2748 rk_clrsetreg(&cru->clksel_con[con_id], mask, 2749 ACLK_RKVDEC_SEL_CPLL << shift); 2750 } else { 2751 rk_clrsetreg(&cru->clksel_con[con_id], mask, 2752 ACLK_RKVDEC_SEL_GPLL << shift); 2753 } 2754 2755 return 0; 2756 } 2757 2758 static int rk3568_clk_set_parent(struct clk *clk, struct clk *parent) 2759 { 2760 switch (clk->id) { 2761 case SCLK_GMAC0: 2762 return rk3568_gmac0_src_set_parent(clk, parent); 2763 case SCLK_GMAC1: 2764 return rk3568_gmac1_src_set_parent(clk, parent); 2765 case SCLK_GMAC0_RX_TX: 2766 return rk3568_gmac0_tx_rx_set_parent(clk, parent); 2767 case SCLK_GMAC1_RX_TX: 2768 return rk3568_gmac1_tx_rx_set_parent(clk, parent); 2769 case DCLK_VOP0: 2770 case DCLK_VOP1: 2771 case DCLK_VOP2: 2772 return rk3568_dclk_vop_set_parent(clk, parent); 2773 case ACLK_RKVDEC_PRE: 2774 case CLK_RKVDEC_CORE: 2775 return rk3568_rkvdec_set_parent(clk, parent); 2776 default: 2777 return -ENOENT; 2778 } 2779 2780 return 0; 2781 } 2782 #endif 2783 2784 static struct clk_ops rk3568_clk_ops = { 2785 .get_rate = rk3568_clk_get_rate, 2786 .set_rate = rk3568_clk_set_rate, 2787 .get_phase = rk3568_clk_get_phase, 2788 .set_phase = rk3568_clk_set_phase, 2789 #if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA)) 2790 .set_parent = rk3568_clk_set_parent, 2791 #endif 2792 }; 2793 2794 static void rk3568_clk_init(struct rk3568_clk_priv *priv) 2795 { 2796 int ret; 2797 2798 priv->sync_kernel = false; 2799 if (!priv->armclk_enter_hz) { 2800 priv->armclk_enter_hz = 2801 rockchip_pll_get_rate(&rk3568_pll_clks[APLL], 2802 priv->cru, APLL); 2803 priv->armclk_init_hz = priv->armclk_enter_hz; 2804 } 2805 2806 if (priv->armclk_init_hz != APLL_HZ) { 2807 ret = rk3568_armclk_set_clk(priv, APLL_HZ); 2808 if (!ret) 2809 priv->armclk_init_hz = APLL_HZ; 2810 } 2811 if (priv->cpll_hz != CPLL_HZ) { 2812 ret = rockchip_pll_set_rate(&rk3568_pll_clks[CPLL], priv->cru, 2813 CPLL, CPLL_HZ); 2814 if (!ret) 2815 priv->cpll_hz = CPLL_HZ; 2816 } 2817 if (priv->gpll_hz != GPLL_HZ) { 2818 ret = rockchip_pll_set_rate(&rk3568_pll_clks[GPLL], priv->cru, 2819 GPLL, GPLL_HZ); 2820 if (!ret) 2821 priv->gpll_hz = GPLL_HZ; 2822 } 2823 2824 #ifdef CONFIG_SPL_BUILD 2825 ret = rk3568_bus_set_clk(priv, ACLK_BUS, 150000000); 2826 if (ret < 0) 2827 printf("Fail to set the ACLK_BUS clock.\n"); 2828 #endif 2829 2830 priv->ppll_hz = rk3568_pmu_pll_get_rate(priv, PPLL); 2831 priv->hpll_hz = rk3568_pmu_pll_get_rate(priv, HPLL); 2832 } 2833 2834 static int rk3568_clk_probe(struct udevice *dev) 2835 { 2836 struct rk3568_clk_priv *priv = dev_get_priv(dev); 2837 int ret; 2838 2839 priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 2840 if (IS_ERR(priv->grf)) 2841 return PTR_ERR(priv->grf); 2842 2843 rk3568_clk_init(priv); 2844 2845 /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */ 2846 ret = clk_set_defaults(dev); 2847 if (ret) 2848 debug("%s clk_set_defaults failed %d\n", __func__, ret); 2849 else 2850 priv->sync_kernel = true; 2851 2852 return 0; 2853 } 2854 2855 static int rk3568_clk_ofdata_to_platdata(struct udevice *dev) 2856 { 2857 struct rk3568_clk_priv *priv = dev_get_priv(dev); 2858 2859 priv->cru = dev_read_addr_ptr(dev); 2860 2861 return 0; 2862 } 2863 2864 static int rk3568_clk_bind(struct udevice *dev) 2865 { 2866 int ret; 2867 struct udevice *sys_child, *sf_child; 2868 struct sysreset_reg *priv; 2869 struct softreset_reg *sf_priv; 2870 2871 /* The reset driver does not have a device node, so bind it here */ 2872 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset", 2873 &sys_child); 2874 if (ret) { 2875 debug("Warning: No sysreset driver: ret=%d\n", ret); 2876 } else { 2877 priv = malloc(sizeof(struct sysreset_reg)); 2878 priv->glb_srst_fst_value = offsetof(struct rk3568_cru, 2879 glb_srst_fst); 2880 priv->glb_srst_snd_value = offsetof(struct rk3568_cru, 2881 glb_srsr_snd); 2882 sys_child->priv = priv; 2883 } 2884 2885 ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset", 2886 dev_ofnode(dev), &sf_child); 2887 if (ret) { 2888 debug("Warning: No rockchip reset driver: ret=%d\n", ret); 2889 } else { 2890 sf_priv = malloc(sizeof(struct softreset_reg)); 2891 sf_priv->sf_reset_offset = offsetof(struct rk3568_cru, 2892 softrst_con[0]); 2893 sf_priv->sf_reset_num = 30; 2894 sf_child->priv = sf_priv; 2895 } 2896 2897 return 0; 2898 } 2899 2900 static const struct udevice_id rk3568_clk_ids[] = { 2901 { .compatible = "rockchip,rk3568-cru" }, 2902 { } 2903 }; 2904 2905 U_BOOT_DRIVER(rockchip_rk3568_cru) = { 2906 .name = "rockchip_rk3568_cru", 2907 .id = UCLASS_CLK, 2908 .of_match = rk3568_clk_ids, 2909 .priv_auto_alloc_size = sizeof(struct rk3568_clk_priv), 2910 .ofdata_to_platdata = rk3568_clk_ofdata_to_platdata, 2911 .ops = &rk3568_clk_ops, 2912 .bind = rk3568_clk_bind, 2913 .probe = rk3568_clk_probe, 2914 }; 2915 2916 #ifndef CONFIG_SPL_BUILD 2917 /** 2918 * soc_clk_dump() - Print clock frequencies 2919 * Returns zero on success 2920 * 2921 * Implementation for the clk dump command. 2922 */ 2923 int soc_clk_dump(void) 2924 { 2925 struct udevice *cru_dev, *pmucru_dev; 2926 struct rk3568_clk_priv *priv; 2927 const struct rk3568_clk_info *clk_dump; 2928 struct clk clk; 2929 unsigned long clk_count = ARRAY_SIZE(clks_dump); 2930 unsigned long rate; 2931 int i, ret; 2932 2933 ret = uclass_get_device_by_driver(UCLASS_CLK, 2934 DM_GET_DRIVER(rockchip_rk3568_cru), 2935 &cru_dev); 2936 if (ret) { 2937 printf("%s failed to get cru device\n", __func__); 2938 return ret; 2939 } 2940 2941 ret = uclass_get_device_by_driver(UCLASS_CLK, 2942 DM_GET_DRIVER(rockchip_rk3568_pmucru), 2943 &pmucru_dev); 2944 if (ret) { 2945 printf("%s failed to get pmucru device\n", __func__); 2946 return ret; 2947 } 2948 2949 priv = dev_get_priv(cru_dev); 2950 printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n", 2951 priv->sync_kernel ? "sync kernel" : "uboot", 2952 priv->armclk_enter_hz / 1000, 2953 priv->armclk_init_hz / 1000, 2954 priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0, 2955 priv->set_armclk_rate ? " KHz" : "N/A"); 2956 for (i = 0; i < clk_count; i++) { 2957 clk_dump = &clks_dump[i]; 2958 if (clk_dump->name) { 2959 clk.id = clk_dump->id; 2960 if (clk_dump->is_cru) 2961 ret = clk_request(cru_dev, &clk); 2962 else 2963 ret = clk_request(pmucru_dev, &clk); 2964 if (ret < 0) 2965 return ret; 2966 2967 rate = clk_get_rate(&clk); 2968 clk_free(&clk); 2969 if (i == 0) { 2970 if (rate < 0) 2971 printf(" %s %s\n", clk_dump->name, 2972 "unknown"); 2973 else 2974 printf(" %s %lu KHz\n", clk_dump->name, 2975 rate / 1000); 2976 } else { 2977 if (rate < 0) 2978 printf(" %s %s\n", clk_dump->name, 2979 "unknown"); 2980 else 2981 printf(" %s %lu KHz\n", clk_dump->name, 2982 rate / 1000); 2983 } 2984 } 2985 } 2986 2987 return 0; 2988 } 2989 #endif 2990