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