1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2021 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_rk3588.h> 15 #include <asm/arch/hardware.h> 16 #include <asm/io.h> 17 #include <dm/lists.h> 18 #include <dt-bindings/clock/rk3588-cru.h> 19 20 DECLARE_GLOBAL_DATA_PTR; 21 22 #define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1)) 23 24 static struct rockchip_pll_rate_table rk3588_pll_rates[] = { 25 /* _mhz, _p, _m, _s, _k */ 26 RK3588_PLL_RATE(1500000000, 2, 250, 1, 0), 27 RK3588_PLL_RATE(1200000000, 2, 200, 1, 0), 28 RK3588_PLL_RATE(1188000000, 2, 198, 1, 0), 29 RK3588_PLL_RATE(1008000000, 2, 336, 2, 0), 30 RK3588_PLL_RATE(1000000000, 3, 500, 2, 0), 31 RK3588_PLL_RATE(900000000, 2, 300, 2, 0), 32 RK3588_PLL_RATE(850000000, 3, 425, 2, 0), 33 RK3588_PLL_RATE(816000000, 2, 272, 2, 0), 34 RK3588_PLL_RATE(786000000, 1, 131, 2, 0), 35 RK3588_PLL_RATE(600000000, 2, 200, 2, 0), 36 RK3588_PLL_RATE(594000000, 2, 198, 2, 0), 37 RK3588_PLL_RATE(200000000, 3, 400, 4, 0), 38 RK3588_PLL_RATE(100000000, 3, 400, 5, 0), 39 { /* sentinel */ }, 40 }; 41 42 static struct rockchip_pll_clock rk3588_pll_clks[] = { 43 [B0PLL] = PLL(pll_rk3588, PLL_B0PLL, RK3588_B0_PLL_CON(0), 44 RK3588_B0_PLL_MODE_CON, 0, 15, 0, 45 rk3588_pll_rates), 46 [B1PLL] = PLL(pll_rk3588, PLL_B1PLL, RK3588_B1_PLL_CON(8), 47 RK3588_B1_PLL_MODE_CON, 0, 15, 0, 48 rk3588_pll_rates), 49 [LPLL] = PLL(pll_rk3588, PLL_LPLL, RK3588_LPLL_CON(16), 50 RK3588_LPLL_MODE_CON, 0, 15, 0, rk3588_pll_rates), 51 [V0PLL] = PLL(pll_rk3588, PLL_V0PLL, RK3588_PLL_CON(88), 52 RK3588_MODE_CON0, 4, 15, 0, rk3588_pll_rates), 53 [AUPLL] = PLL(pll_rk3588, PLL_AUPLL, RK3588_PLL_CON(96), 54 RK3588_MODE_CON0, 6, 15, 0, rk3588_pll_rates), 55 [CPLL] = PLL(pll_rk3588, PLL_CPLL, RK3588_PLL_CON(104), 56 RK3588_MODE_CON0, 8, 15, 0, rk3588_pll_rates), 57 [GPLL] = PLL(pll_rk3588, PLL_GPLL, RK3588_PLL_CON(112), 58 RK3588_MODE_CON0, 2, 15, 0, rk3588_pll_rates), 59 [NPLL] = PLL(pll_rk3588, PLL_NPLL, RK3588_PLL_CON(120), 60 RK3588_MODE_CON0, 0, 15, 0, rk3588_pll_rates), 61 [PPLL] = PLL(pll_rk3588, PLL_PPLL, RK3588_PMU_PLL_CON(128), 62 RK3588_MODE_CON0, 10, 15, 0, rk3588_pll_rates), 63 }; 64 65 #ifndef CONFIG_SPL_BUILD 66 #define RK3588_CLK_DUMP(_id, _name, _iscru) \ 67 { \ 68 .id = _id, \ 69 .name = _name, \ 70 .is_cru = _iscru, \ 71 } 72 73 static const struct rk3588_clk_info clks_dump[] = { 74 RK3588_CLK_DUMP(PLL_B0PLL, "b0pll", true), 75 RK3588_CLK_DUMP(PLL_B1PLL, "b1pll", true), 76 RK3588_CLK_DUMP(PLL_LPLL, "lpll", true), 77 RK3588_CLK_DUMP(PLL_V0PLL, "v0pll", true), 78 RK3588_CLK_DUMP(PLL_AUPLL, "aupll", true), 79 RK3588_CLK_DUMP(PLL_CPLL, "cpll", true), 80 RK3588_CLK_DUMP(PLL_GPLL, "gpll", true), 81 RK3588_CLK_DUMP(PLL_NPLL, "npll", true), 82 RK3588_CLK_DUMP(PLL_PPLL, "ppll", true), 83 RK3588_CLK_DUMP(ACLK_CENTER_ROOT, "aclk_center_root", true), 84 RK3588_CLK_DUMP(PCLK_CENTER_ROOT, "pclk_center_root", true), 85 RK3588_CLK_DUMP(HCLK_CENTER_ROOT, "hclk_center_root", true), 86 RK3588_CLK_DUMP(ACLK_CENTER_LOW_ROOT, "aclk_center_low_root", true), 87 RK3588_CLK_DUMP(ACLK_TOP_ROOT, "aclk_top_root", true), 88 RK3588_CLK_DUMP(PCLK_TOP_ROOT, "pclk_top_root", true), 89 RK3588_CLK_DUMP(ACLK_LOW_TOP_ROOT, "aclk_low_top_root", true), 90 }; 91 #endif 92 93 #ifndef CONFIG_SPL_BUILD 94 /* 95 * 96 * rational_best_approximation(31415, 10000, 97 * (1 << 8) - 1, (1 << 5) - 1, &n, &d); 98 * 99 * you may look at given_numerator as a fixed point number, 100 * with the fractional part size described in given_denominator. 101 * 102 * for theoretical background, see: 103 * http://en.wikipedia.org/wiki/Continued_fraction 104 */ 105 static void rational_best_approximation(unsigned long given_numerator, 106 unsigned long given_denominator, 107 unsigned long max_numerator, 108 unsigned long max_denominator, 109 unsigned long *best_numerator, 110 unsigned long *best_denominator) 111 { 112 unsigned long n, d, n0, d0, n1, d1; 113 114 n = given_numerator; 115 d = given_denominator; 116 n0 = 0; 117 d1 = 0; 118 n1 = 1; 119 d0 = 1; 120 for (;;) { 121 unsigned long t, a; 122 123 if (n1 > max_numerator || d1 > max_denominator) { 124 n1 = n0; 125 d1 = d0; 126 break; 127 } 128 if (d == 0) 129 break; 130 t = d; 131 a = n / d; 132 d = n % d; 133 n = t; 134 t = n0 + a * n1; 135 n0 = n1; 136 n1 = t; 137 t = d0 + a * d1; 138 d0 = d1; 139 d1 = t; 140 } 141 *best_numerator = n1; 142 *best_denominator = d1; 143 } 144 #endif 145 146 static ulong rk3588_center_get_clk(struct rk3588_clk_priv *priv, ulong clk_id) 147 { 148 struct rk3588_cru *cru = priv->cru; 149 u32 con, sel, rate; 150 151 switch (clk_id) { 152 case ACLK_CENTER_ROOT: 153 con = readl(&cru->clksel_con[165]); 154 sel = (con & ACLK_CENTER_ROOT_SEL_MASK) >> 155 ACLK_CENTER_ROOT_SEL_SHIFT; 156 if (sel == ACLK_CENTER_ROOT_SEL_700M) 157 rate = 702 * MHz; 158 else if (sel == ACLK_CENTER_ROOT_SEL_400M) 159 rate = 396 * MHz; 160 else if (sel == ACLK_CENTER_ROOT_SEL_200M) 161 rate = 200 * MHz; 162 else 163 rate = OSC_HZ; 164 break; 165 case ACLK_CENTER_LOW_ROOT: 166 con = readl(&cru->clksel_con[165]); 167 sel = (con & ACLK_CENTER_LOW_ROOT_SEL_MASK) >> 168 ACLK_CENTER_LOW_ROOT_SEL_SHIFT; 169 if (sel == ACLK_CENTER_LOW_ROOT_SEL_500M) 170 rate = 500 * MHz; 171 else if (sel == ACLK_CENTER_LOW_ROOT_SEL_250M) 172 rate = 250 * MHz; 173 else if (sel == ACLK_CENTER_LOW_ROOT_SEL_100M) 174 rate = 100 * MHz; 175 else 176 rate = OSC_HZ; 177 break; 178 case HCLK_CENTER_ROOT: 179 con = readl(&cru->clksel_con[165]); 180 sel = (con & HCLK_CENTER_ROOT_SEL_MASK) >> 181 HCLK_CENTER_ROOT_SEL_SHIFT; 182 if (sel == HCLK_CENTER_ROOT_SEL_400M) 183 rate = 396 * MHz; 184 else if (sel == HCLK_CENTER_ROOT_SEL_200M) 185 rate = 200 * MHz; 186 else if (sel == HCLK_CENTER_ROOT_SEL_100M) 187 rate = 100 * MHz; 188 else 189 rate = OSC_HZ; 190 break; 191 case PCLK_CENTER_ROOT: 192 con = readl(&cru->clksel_con[165]); 193 sel = (con & PCLK_CENTER_ROOT_SEL_MASK) >> 194 PCLK_CENTER_ROOT_SEL_SHIFT; 195 if (sel == PCLK_CENTER_ROOT_SEL_200M) 196 rate = 200 * MHz; 197 else if (sel == PCLK_CENTER_ROOT_SEL_100M) 198 rate = 100 * MHz; 199 else if (sel == PCLK_CENTER_ROOT_SEL_50M) 200 rate = 50 * MHz; 201 else 202 rate = OSC_HZ; 203 break; 204 default: 205 return -ENOENT; 206 } 207 208 return rate; 209 } 210 211 static ulong rk3588_center_set_clk(struct rk3588_clk_priv *priv, 212 ulong clk_id, ulong rate) 213 { 214 struct rk3588_cru *cru = priv->cru; 215 int src_clk; 216 217 switch (clk_id) { 218 case ACLK_CENTER_ROOT: 219 if (rate >= 700 * MHz) 220 src_clk = ACLK_CENTER_ROOT_SEL_700M; 221 else if (rate >= 396 * MHz) 222 src_clk = ACLK_CENTER_ROOT_SEL_400M; 223 else if (rate >= 200 * MHz) 224 src_clk = ACLK_CENTER_ROOT_SEL_200M; 225 else 226 src_clk = ACLK_CENTER_ROOT_SEL_24M; 227 rk_clrsetreg(&cru->clksel_con[165], 228 ACLK_CENTER_ROOT_SEL_MASK, 229 src_clk << ACLK_CENTER_ROOT_SEL_SHIFT); 230 break; 231 case ACLK_CENTER_LOW_ROOT: 232 if (rate >= 500 * MHz) 233 src_clk = ACLK_CENTER_LOW_ROOT_SEL_500M; 234 else if (rate >= 250 * MHz) 235 src_clk = ACLK_CENTER_LOW_ROOT_SEL_250M; 236 else if (rate >= 99 * MHz) 237 src_clk = ACLK_CENTER_LOW_ROOT_SEL_100M; 238 else 239 src_clk = ACLK_CENTER_LOW_ROOT_SEL_24M; 240 rk_clrsetreg(&cru->clksel_con[165], 241 ACLK_CENTER_LOW_ROOT_SEL_MASK, 242 src_clk << ACLK_CENTER_LOW_ROOT_SEL_SHIFT); 243 break; 244 case HCLK_CENTER_ROOT: 245 if (rate >= 396 * MHz) 246 src_clk = HCLK_CENTER_ROOT_SEL_400M; 247 else if (rate >= 198 * MHz) 248 src_clk = HCLK_CENTER_ROOT_SEL_200M; 249 else if (rate >= 99 * MHz) 250 src_clk = HCLK_CENTER_ROOT_SEL_100M; 251 else 252 src_clk = HCLK_CENTER_ROOT_SEL_24M; 253 rk_clrsetreg(&cru->clksel_con[165], 254 HCLK_CENTER_ROOT_SEL_MASK, 255 src_clk << HCLK_CENTER_ROOT_SEL_SHIFT); 256 break; 257 case PCLK_CENTER_ROOT: 258 if (rate >= 198 * MHz) 259 src_clk = PCLK_CENTER_ROOT_SEL_200M; 260 else if (rate >= 99 * MHz) 261 src_clk = PCLK_CENTER_ROOT_SEL_100M; 262 else if (rate >= 50 * MHz) 263 src_clk = PCLK_CENTER_ROOT_SEL_50M; 264 else 265 src_clk = PCLK_CENTER_ROOT_SEL_24M; 266 rk_clrsetreg(&cru->clksel_con[165], 267 PCLK_CENTER_ROOT_SEL_MASK, 268 src_clk << PCLK_CENTER_ROOT_SEL_SHIFT); 269 break; 270 default: 271 printf("do not support this center freq\n"); 272 return -EINVAL; 273 } 274 275 return rk3588_center_get_clk(priv, clk_id); 276 } 277 278 static ulong rk3588_top_get_clk(struct rk3588_clk_priv *priv, ulong clk_id) 279 { 280 struct rk3588_cru *cru = priv->cru; 281 u32 con, sel, div, rate, prate; 282 283 switch (clk_id) { 284 case ACLK_TOP_ROOT: 285 con = readl(&cru->clksel_con[8]); 286 div = (con & ACLK_TOP_ROOT_DIV_MASK) >> 287 ACLK_TOP_ROOT_DIV_SHIFT; 288 sel = (con & ACLK_TOP_ROOT_SRC_SEL_MASK) >> 289 ACLK_TOP_ROOT_SRC_SEL_SHIFT; 290 if (sel == ACLK_TOP_ROOT_SRC_SEL_CPLL) 291 prate = priv->cpll_hz; 292 else 293 prate = priv->cpll_hz; 294 return DIV_TO_RATE(prate, div); 295 case ACLK_LOW_TOP_ROOT: 296 con = readl(&cru->clksel_con[8]); 297 div = (con & ACLK_LOW_TOP_ROOT_DIV_MASK) >> 298 ACLK_LOW_TOP_ROOT_DIV_SHIFT; 299 sel = (con & ACLK_LOW_TOP_ROOT_SRC_SEL_MASK) >> 300 ACLK_LOW_TOP_ROOT_SRC_SEL_SHIFT; 301 if (sel == ACLK_LOW_TOP_ROOT_SRC_SEL_CPLL) 302 prate = priv->cpll_hz; 303 else 304 prate = priv->gpll_hz; 305 return DIV_TO_RATE(prate, div); 306 case PCLK_TOP_ROOT: 307 con = readl(&cru->clksel_con[8]); 308 sel = (con & PCLK_TOP_ROOT_SEL_MASK) >> PCLK_TOP_ROOT_SEL_SHIFT; 309 if (sel == PCLK_TOP_ROOT_SEL_100M) 310 rate = 100 * MHz; 311 else if (sel == PCLK_TOP_ROOT_SEL_50M) 312 rate = 50 * MHz; 313 else 314 rate = OSC_HZ; 315 break; 316 default: 317 return -ENOENT; 318 } 319 320 return rate; 321 } 322 323 static ulong rk3588_top_set_clk(struct rk3588_clk_priv *priv, 324 ulong clk_id, ulong rate) 325 { 326 struct rk3588_cru *cru = priv->cru; 327 int src_clk, src_clk_div; 328 329 switch (clk_id) { 330 case ACLK_TOP_ROOT: 331 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); 332 assert(src_clk_div - 1 <= 31); 333 rk_clrsetreg(&cru->clksel_con[8], 334 ACLK_TOP_ROOT_DIV_MASK | 335 ACLK_TOP_ROOT_SRC_SEL_MASK, 336 (ACLK_TOP_ROOT_SRC_SEL_GPLL << 337 ACLK_TOP_ROOT_SRC_SEL_SHIFT) | 338 (src_clk_div - 1) << ACLK_TOP_ROOT_DIV_SHIFT); 339 break; 340 case ACLK_LOW_TOP_ROOT: 341 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); 342 assert(src_clk_div - 1 <= 31); 343 rk_clrsetreg(&cru->clksel_con[8], 344 ACLK_LOW_TOP_ROOT_DIV_MASK | 345 ACLK_LOW_TOP_ROOT_SRC_SEL_MASK, 346 (ACLK_LOW_TOP_ROOT_SRC_SEL_GPLL << 347 ACLK_LOW_TOP_ROOT_SRC_SEL_SHIFT) | 348 (src_clk_div - 1) << ACLK_LOW_TOP_ROOT_DIV_SHIFT); 349 break; 350 case PCLK_TOP_ROOT: 351 if (rate == 100 * MHz) 352 src_clk = PCLK_TOP_ROOT_SEL_100M; 353 else if (rate == 50 * MHz) 354 src_clk = PCLK_TOP_ROOT_SEL_50M; 355 else 356 src_clk = PCLK_TOP_ROOT_SEL_24M; 357 rk_clrsetreg(&cru->clksel_con[8], 358 PCLK_TOP_ROOT_SEL_MASK, 359 src_clk << PCLK_TOP_ROOT_SEL_SHIFT); 360 break; 361 default: 362 printf("do not support this top freq\n"); 363 return -EINVAL; 364 } 365 366 return rk3588_top_get_clk(priv, clk_id); 367 } 368 369 static ulong rk3588_i2c_get_clk(struct rk3588_clk_priv *priv, ulong clk_id) 370 { 371 struct rk3588_cru *cru = priv->cru; 372 u32 sel, con; 373 ulong rate; 374 375 switch (clk_id) { 376 case CLK_I2C0: 377 con = readl(&cru->pmuclksel_con[3]); 378 sel = (con & CLK_I2C0_SEL_MASK) >> CLK_I2C0_SEL_SHIFT; 379 break; 380 case CLK_I2C1: 381 con = readl(&cru->clksel_con[38]); 382 sel = (con & CLK_I2C1_SEL_MASK) >> CLK_I2C1_SEL_SHIFT; 383 break; 384 case CLK_I2C2: 385 con = readl(&cru->clksel_con[38]); 386 sel = (con & CLK_I2C2_SEL_MASK) >> CLK_I2C2_SEL_SHIFT; 387 break; 388 case CLK_I2C3: 389 con = readl(&cru->clksel_con[38]); 390 sel = (con & CLK_I2C3_SEL_MASK) >> CLK_I2C3_SEL_SHIFT; 391 break; 392 case CLK_I2C4: 393 con = readl(&cru->clksel_con[38]); 394 sel = (con & CLK_I2C4_SEL_MASK) >> CLK_I2C4_SEL_SHIFT; 395 break; 396 case CLK_I2C5: 397 con = readl(&cru->clksel_con[38]); 398 sel = (con & CLK_I2C5_SEL_MASK) >> CLK_I2C5_SEL_SHIFT; 399 break; 400 case CLK_I2C6: 401 con = readl(&cru->clksel_con[38]); 402 sel = (con & CLK_I2C6_SEL_MASK) >> CLK_I2C6_SEL_SHIFT; 403 break; 404 case CLK_I2C7: 405 con = readl(&cru->clksel_con[38]); 406 sel = (con & CLK_I2C7_SEL_MASK) >> CLK_I2C7_SEL_SHIFT; 407 break; 408 case CLK_I2C8: 409 con = readl(&cru->clksel_con[38]); 410 sel = (con & CLK_I2C8_SEL_MASK) >> CLK_I2C8_SEL_SHIFT; 411 break; 412 default: 413 return -ENOENT; 414 } 415 if (sel == CLK_I2C_SEL_200M) 416 rate = 200 * MHz; 417 else 418 rate = 100 * MHz; 419 420 return rate; 421 } 422 423 static ulong rk3588_i2c_set_clk(struct rk3588_clk_priv *priv, ulong clk_id, 424 ulong rate) 425 { 426 struct rk3588_cru *cru = priv->cru; 427 int src_clk; 428 429 if (rate >= 198 * MHz) 430 src_clk = CLK_I2C_SEL_200M; 431 else 432 src_clk = CLK_I2C_SEL_100M; 433 434 switch (clk_id) { 435 case CLK_I2C0: 436 rk_clrsetreg(&cru->pmuclksel_con[3], CLK_I2C0_SEL_MASK, 437 src_clk << CLK_I2C0_SEL_SHIFT); 438 break; 439 case CLK_I2C1: 440 rk_clrsetreg(&cru->clksel_con[38], CLK_I2C1_SEL_MASK, 441 src_clk << CLK_I2C1_SEL_SHIFT); 442 break; 443 case CLK_I2C2: 444 rk_clrsetreg(&cru->clksel_con[38], CLK_I2C2_SEL_MASK, 445 src_clk << CLK_I2C2_SEL_SHIFT); 446 break; 447 case CLK_I2C3: 448 rk_clrsetreg(&cru->clksel_con[38], CLK_I2C3_SEL_MASK, 449 src_clk << CLK_I2C3_SEL_SHIFT); 450 break; 451 case CLK_I2C4: 452 rk_clrsetreg(&cru->clksel_con[38], CLK_I2C4_SEL_MASK, 453 src_clk << CLK_I2C4_SEL_SHIFT); 454 break; 455 case CLK_I2C5: 456 rk_clrsetreg(&cru->clksel_con[38], CLK_I2C5_SEL_MASK, 457 src_clk << CLK_I2C5_SEL_SHIFT); 458 break; 459 case CLK_I2C6: 460 rk_clrsetreg(&cru->clksel_con[38], CLK_I2C6_SEL_MASK, 461 src_clk << CLK_I2C6_SEL_SHIFT); 462 break; 463 case CLK_I2C7: 464 rk_clrsetreg(&cru->clksel_con[38], CLK_I2C7_SEL_MASK, 465 src_clk << CLK_I2C7_SEL_SHIFT); 466 break; 467 case CLK_I2C8: 468 rk_clrsetreg(&cru->clksel_con[38], CLK_I2C8_SEL_MASK, 469 src_clk << CLK_I2C8_SEL_SHIFT); 470 break; 471 default: 472 return -ENOENT; 473 } 474 475 return rk3588_i2c_get_clk(priv, clk_id); 476 } 477 478 static ulong rk3588_spi_get_clk(struct rk3588_clk_priv *priv, ulong clk_id) 479 { 480 struct rk3588_cru *cru = priv->cru; 481 u32 sel, con; 482 483 con = readl(&cru->clksel_con[59]); 484 485 switch (clk_id) { 486 case CLK_SPI0: 487 sel = (con & CLK_SPI0_SEL_MASK) >> CLK_SPI0_SEL_SHIFT; 488 break; 489 case CLK_SPI1: 490 sel = (con & CLK_SPI1_SEL_MASK) >> CLK_SPI1_SEL_SHIFT; 491 break; 492 case CLK_SPI2: 493 sel = (con & CLK_SPI2_SEL_MASK) >> CLK_SPI2_SEL_SHIFT; 494 break; 495 case CLK_SPI3: 496 sel = (con & CLK_SPI3_SEL_MASK) >> CLK_SPI3_SEL_SHIFT; 497 break; 498 case CLK_SPI4: 499 sel = (con & CLK_SPI4_SEL_MASK) >> CLK_SPI4_SEL_SHIFT; 500 break; 501 default: 502 return -ENOENT; 503 } 504 505 switch (sel) { 506 case CLK_SPI_SEL_200M: 507 return 200 * MHz; 508 case CLK_SPI_SEL_150M: 509 return 150 * MHz; 510 case CLK_SPI_SEL_24M: 511 return OSC_HZ; 512 default: 513 return -ENOENT; 514 } 515 } 516 517 static ulong rk3588_spi_set_clk(struct rk3588_clk_priv *priv, 518 ulong clk_id, ulong rate) 519 { 520 struct rk3588_cru *cru = priv->cru; 521 int src_clk; 522 523 if (rate >= 198 * MHz) 524 src_clk = CLK_SPI_SEL_200M; 525 else if (rate >= 140 * MHz) 526 src_clk = CLK_SPI_SEL_150M; 527 else 528 src_clk = CLK_SPI_SEL_24M; 529 530 switch (clk_id) { 531 case CLK_SPI0: 532 rk_clrsetreg(&cru->clksel_con[59], 533 CLK_SPI0_SEL_MASK, 534 src_clk << CLK_SPI0_SEL_SHIFT); 535 break; 536 case CLK_SPI1: 537 rk_clrsetreg(&cru->clksel_con[59], 538 CLK_SPI1_SEL_MASK, 539 src_clk << CLK_SPI1_SEL_SHIFT); 540 break; 541 case CLK_SPI2: 542 rk_clrsetreg(&cru->clksel_con[59], 543 CLK_SPI2_SEL_MASK, 544 src_clk << CLK_SPI2_SEL_SHIFT); 545 break; 546 case CLK_SPI3: 547 rk_clrsetreg(&cru->clksel_con[59], 548 CLK_SPI3_SEL_MASK, 549 src_clk << CLK_SPI3_SEL_SHIFT); 550 break; 551 case CLK_SPI4: 552 rk_clrsetreg(&cru->clksel_con[59], 553 CLK_SPI4_SEL_MASK, 554 src_clk << CLK_SPI4_SEL_SHIFT); 555 break; 556 default: 557 return -ENOENT; 558 } 559 560 return rk3588_spi_get_clk(priv, clk_id); 561 } 562 563 static ulong rk3588_pwm_get_clk(struct rk3588_clk_priv *priv, ulong clk_id) 564 { 565 struct rk3588_cru *cru = priv->cru; 566 u32 sel, con; 567 568 switch (clk_id) { 569 case CLK_PWM1: 570 con = readl(&cru->clksel_con[59]); 571 sel = (con & CLK_PWM1_SEL_MASK) >> CLK_PWM3_SEL_SHIFT; 572 break; 573 case CLK_PWM2: 574 con = readl(&cru->clksel_con[59]); 575 sel = (con & CLK_PWM2_SEL_MASK) >> CLK_PWM2_SEL_SHIFT; 576 break; 577 case CLK_PWM3: 578 con = readl(&cru->clksel_con[60]); 579 sel = (con & CLK_PWM3_SEL_MASK) >> CLK_PWM3_SEL_SHIFT; 580 break; 581 default: 582 return -ENOENT; 583 } 584 585 switch (sel) { 586 case CLK_PWM_SEL_100M: 587 return 100 * MHz; 588 case CLK_PWM_SEL_50M: 589 return 50 * MHz; 590 case CLK_PWM_SEL_24M: 591 return OSC_HZ; 592 default: 593 return -ENOENT; 594 } 595 } 596 597 static ulong rk3588_pwm_set_clk(struct rk3588_clk_priv *priv, 598 ulong clk_id, ulong rate) 599 { 600 struct rk3588_cru *cru = priv->cru; 601 int src_clk; 602 603 if (rate >= 99 * MHz) 604 src_clk = CLK_PWM_SEL_100M; 605 else if (rate >= 50 * MHz) 606 src_clk = CLK_PWM_SEL_50M; 607 else 608 src_clk = CLK_PWM_SEL_24M; 609 610 switch (clk_id) { 611 case CLK_PWM1: 612 rk_clrsetreg(&cru->clksel_con[59], 613 CLK_PWM1_SEL_MASK, 614 src_clk << CLK_PWM1_SEL_SHIFT); 615 break; 616 case CLK_PWM2: 617 rk_clrsetreg(&cru->clksel_con[59], 618 CLK_PWM2_SEL_MASK, 619 src_clk << CLK_PWM2_SEL_SHIFT); 620 break; 621 case CLK_PWM3: 622 rk_clrsetreg(&cru->clksel_con[60], 623 CLK_PWM3_SEL_MASK, 624 src_clk << CLK_PWM3_SEL_SHIFT); 625 break; 626 default: 627 return -ENOENT; 628 } 629 630 return rk3588_pwm_get_clk(priv, clk_id); 631 } 632 633 static ulong rk3588_adc_get_clk(struct rk3588_clk_priv *priv, ulong clk_id) 634 { 635 struct rk3588_cru *cru = priv->cru; 636 u32 div, sel, con, prate; 637 638 switch (clk_id) { 639 case CLK_SARADC: 640 con = readl(&cru->clksel_con[40]); 641 div = (con & CLK_SARADC_DIV_MASK) >> CLK_SARADC_DIV_SHIFT; 642 sel = (con & CLK_SARADC_SEL_MASK) >> 643 CLK_SARADC_SEL_SHIFT; 644 if (sel == CLK_SARADC_SEL_24M) 645 prate = OSC_HZ; 646 else 647 prate = priv->gpll_hz; 648 return DIV_TO_RATE(prate, div); 649 case CLK_TSADC: 650 con = readl(&cru->clksel_con[41]); 651 div = (con & CLK_TSADC_DIV_MASK) >> 652 CLK_TSADC_DIV_SHIFT; 653 sel = (con & CLK_TSADC_SEL_MASK) >> 654 CLK_TSADC_SEL_SHIFT; 655 if (sel == CLK_TSADC_SEL_24M) 656 prate = OSC_HZ; 657 else 658 prate = 100 * MHz; 659 return DIV_TO_RATE(prate, div); 660 default: 661 return -ENOENT; 662 } 663 } 664 665 static ulong rk3588_adc_set_clk(struct rk3588_clk_priv *priv, 666 ulong clk_id, ulong rate) 667 { 668 struct rk3588_cru *cru = priv->cru; 669 int src_clk_div; 670 671 switch (clk_id) { 672 case CLK_SARADC: 673 if (!(OSC_HZ % rate)) { 674 src_clk_div = DIV_ROUND_UP(OSC_HZ, rate); 675 assert(src_clk_div - 1 <= 255); 676 rk_clrsetreg(&cru->clksel_con[40], 677 CLK_SARADC_SEL_MASK | 678 CLK_SARADC_DIV_MASK, 679 (CLK_SARADC_SEL_24M << 680 CLK_SARADC_SEL_SHIFT) | 681 (src_clk_div - 1) << 682 CLK_SARADC_DIV_SHIFT); 683 } else { 684 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); 685 assert(src_clk_div - 1 <= 255); 686 rk_clrsetreg(&cru->clksel_con[40], 687 CLK_SARADC_SEL_MASK | 688 CLK_SARADC_DIV_MASK, 689 (CLK_SARADC_SEL_GPLL << 690 CLK_SARADC_SEL_SHIFT) | 691 (src_clk_div - 1) << 692 CLK_SARADC_DIV_SHIFT); 693 } 694 break; 695 case CLK_TSADC: 696 if (!(OSC_HZ % rate)) { 697 src_clk_div = DIV_ROUND_UP(OSC_HZ, rate); 698 assert(src_clk_div - 1 <= 255); 699 rk_clrsetreg(&cru->clksel_con[41], 700 CLK_TSADC_SEL_MASK | 701 CLK_TSADC_DIV_MASK, 702 (CLK_TSADC_SEL_24M << 703 CLK_TSADC_SEL_SHIFT) | 704 (src_clk_div - 1) << 705 CLK_TSADC_DIV_SHIFT); 706 } else { 707 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); 708 assert(src_clk_div - 1 <= 7); 709 rk_clrsetreg(&cru->clksel_con[41], 710 CLK_TSADC_SEL_MASK | 711 CLK_TSADC_DIV_MASK, 712 (CLK_TSADC_SEL_GPLL << 713 CLK_TSADC_SEL_SHIFT) | 714 (src_clk_div - 1) << 715 CLK_TSADC_DIV_SHIFT); 716 } 717 break; 718 default: 719 return -ENOENT; 720 } 721 return rk3588_adc_get_clk(priv, clk_id); 722 } 723 724 static ulong rk3588_mmc_get_clk(struct rk3588_clk_priv *priv, ulong clk_id) 725 { 726 struct rk3588_cru *cru = priv->cru; 727 u32 sel, con, div, prate; 728 729 switch (clk_id) { 730 case CCLK_SRC_SDIO: 731 con = readl(&cru->clksel_con[172]); 732 div = (con & CCLK_SDIO_SRC_DIV_MASK) >> CCLK_SDIO_SRC_DIV_SHIFT; 733 sel = (con & CCLK_SDIO_SRC_SEL_MASK) >> 734 CCLK_SDIO_SRC_SEL_SHIFT; 735 if (sel == CCLK_SDIO_SRC_SEL_GPLL) 736 prate = priv->gpll_hz; 737 else if (sel == CCLK_SDIO_SRC_SEL_CPLL) 738 prate = priv->cpll_hz; 739 else 740 prate = OSC_HZ; 741 return DIV_TO_RATE(prate, div); 742 case CCLK_EMMC: 743 con = readl(&cru->clksel_con[77]); 744 div = (con & CCLK_EMMC_DIV_MASK) >> CCLK_EMMC_DIV_SHIFT; 745 sel = (con & CCLK_EMMC_SEL_MASK) >> 746 CCLK_EMMC_SEL_SHIFT; 747 if (sel == CCLK_EMMC_SEL_GPLL) 748 prate = priv->gpll_hz; 749 else if (sel == CCLK_EMMC_SEL_CPLL) 750 prate = priv->cpll_hz; 751 else 752 prate = OSC_HZ; 753 return DIV_TO_RATE(prate, div); 754 case BCLK_EMMC: 755 con = readl(&cru->clksel_con[78]); 756 div = (con & BCLK_EMMC_DIV_MASK) >> BCLK_EMMC_DIV_SHIFT; 757 sel = (con & BCLK_EMMC_SEL_MASK) >> 758 BCLK_EMMC_SEL_SHIFT; 759 if (sel == CCLK_EMMC_SEL_CPLL) 760 prate = priv->cpll_hz; 761 else 762 prate = priv->gpll_hz; 763 return DIV_TO_RATE(prate, div); 764 case SCLK_SFC: 765 con = readl(&cru->clksel_con[78]); 766 div = (con & SCLK_SFC_DIV_MASK) >> SCLK_SFC_DIV_SHIFT; 767 sel = (con & SCLK_SFC_SEL_MASK) >> 768 SCLK_SFC_SEL_SHIFT; 769 if (sel == SCLK_SFC_SEL_GPLL) 770 prate = priv->gpll_hz; 771 else if (sel == SCLK_SFC_SEL_CPLL) 772 prate = priv->cpll_hz; 773 else 774 prate = OSC_HZ; 775 return DIV_TO_RATE(prate, div); 776 case DCLK_DECOM: 777 con = readl(&cru->clksel_con[62]); 778 div = (con & DCLK_DECOM_DIV_MASK) >> DCLK_DECOM_DIV_SHIFT; 779 sel = (con & DCLK_DECOM_SEL_MASK) >> 780 DCLK_DECOM_SEL_SHIFT; 781 if (sel == DCLK_DECOM_SEL_SPLL) 782 prate = 702 * MHz; 783 else 784 prate = priv->gpll_hz; 785 return DIV_TO_RATE(prate, div); 786 default: 787 return -ENOENT; 788 } 789 } 790 791 static ulong rk3588_mmc_set_clk(struct rk3588_clk_priv *priv, 792 ulong clk_id, ulong rate) 793 { 794 struct rk3588_cru *cru = priv->cru; 795 int src_clk, div; 796 797 switch (clk_id) { 798 case CCLK_SRC_SDIO: 799 case CCLK_EMMC: 800 case SCLK_SFC: 801 if (!(OSC_HZ % rate)) { 802 src_clk = SCLK_SFC_SEL_24M; 803 div = DIV_ROUND_UP(OSC_HZ, rate); 804 } else if (!(priv->cpll_hz % rate)) { 805 src_clk = SCLK_SFC_SEL_CPLL; 806 div = DIV_ROUND_UP(priv->cpll_hz, rate); 807 } else { 808 src_clk = SCLK_SFC_SEL_GPLL; 809 div = DIV_ROUND_UP(priv->gpll_hz, rate); 810 } 811 break; 812 case BCLK_EMMC: 813 if (!(priv->cpll_hz % rate)) { 814 src_clk = CCLK_EMMC_SEL_CPLL; 815 div = DIV_ROUND_UP(priv->cpll_hz, rate); 816 } else { 817 src_clk = CCLK_EMMC_SEL_GPLL; 818 div = DIV_ROUND_UP(priv->gpll_hz, rate); 819 } 820 break; 821 case DCLK_DECOM: 822 if (!(702 * MHz % rate)) { 823 src_clk = DCLK_DECOM_SEL_SPLL; 824 div = DIV_ROUND_UP(702 * MHz, rate); 825 } else { 826 src_clk = DCLK_DECOM_SEL_GPLL; 827 div = DIV_ROUND_UP(priv->gpll_hz, rate); 828 } 829 break; 830 default: 831 return -ENOENT; 832 } 833 834 switch (clk_id) { 835 case CCLK_SRC_SDIO: 836 rk_clrsetreg(&cru->clksel_con[172], 837 CCLK_SDIO_SRC_SEL_MASK | 838 CCLK_SDIO_SRC_DIV_MASK, 839 (src_clk << CCLK_SDIO_SRC_SEL_SHIFT) | 840 (div - 1) << CCLK_SDIO_SRC_DIV_SHIFT); 841 break; 842 case CCLK_EMMC: 843 rk_clrsetreg(&cru->clksel_con[77], 844 CCLK_EMMC_SEL_MASK | 845 CCLK_EMMC_DIV_MASK, 846 (src_clk << CCLK_EMMC_SEL_SHIFT) | 847 (div - 1) << CCLK_EMMC_DIV_SHIFT); 848 break; 849 case BCLK_EMMC: 850 rk_clrsetreg(&cru->clksel_con[78], 851 BCLK_EMMC_DIV_MASK | 852 BCLK_EMMC_SEL_MASK, 853 (src_clk << BCLK_EMMC_SEL_SHIFT) | 854 (div - 1) << BCLK_EMMC_DIV_SHIFT); 855 break; 856 case SCLK_SFC: 857 rk_clrsetreg(&cru->clksel_con[78], 858 SCLK_SFC_DIV_MASK | 859 SCLK_SFC_SEL_MASK, 860 (src_clk << SCLK_SFC_SEL_SHIFT) | 861 (div - 1) << SCLK_SFC_DIV_SHIFT); 862 break; 863 case DCLK_DECOM: 864 rk_clrsetreg(&cru->clksel_con[62], 865 DCLK_DECOM_DIV_MASK | 866 DCLK_DECOM_SEL_MASK, 867 (src_clk << DCLK_DECOM_SEL_SHIFT) | 868 (div - 1) << DCLK_DECOM_DIV_SHIFT); 869 break; 870 default: 871 return -ENOENT; 872 } 873 874 return rk3588_mmc_get_clk(priv, clk_id); 875 } 876 877 #ifndef CONFIG_SPL_BUILD 878 static ulong rk3588_aclk_vop_get_clk(struct rk3588_clk_priv *priv, ulong clk_id) 879 { 880 struct rk3588_cru *cru = priv->cru; 881 u32 div, sel, con, parent; 882 883 switch (clk_id) { 884 case ACLK_VOP_ROOT: 885 con = readl(&cru->clksel_con[110]); 886 div = (con & ACLK_VOP_ROOT_DIV_MASK) >> ACLK_VOP_ROOT_DIV_SHIFT; 887 sel = (con & ACLK_VOP_ROOT_SEL_MASK) >> ACLK_VOP_ROOT_SEL_SHIFT; 888 if (sel == ACLK_VOP_ROOT_SEL_GPLL) 889 parent = priv->gpll_hz; 890 else if (sel == ACLK_VOP_ROOT_SEL_CPLL) 891 parent = priv->cpll_hz; 892 else if (sel == ACLK_VOP_ROOT_SEL_AUPLL) 893 parent = priv->aupll_hz; 894 else if (sel == ACLK_VOP_ROOT_SEL_NPLL) 895 parent = priv->npll_hz; 896 else 897 parent = 702 * MHz; 898 return DIV_TO_RATE(parent, div); 899 case ACLK_VOP_LOW_ROOT: 900 con = readl(&cru->clksel_con[110]); 901 sel = (con & ACLK_VOP_LOW_ROOT_SEL_MASK) >> 902 ACLK_VOP_LOW_ROOT_SEL_SHIFT; 903 if (sel == ACLK_VOP_LOW_ROOT_SEL_400M) 904 return 396 * MHz; 905 else if (sel == ACLK_VOP_LOW_ROOT_SEL_200M) 906 return 200 * MHz; 907 else if (sel == ACLK_VOP_LOW_ROOT_SEL_100M) 908 return 100 * MHz; 909 else 910 return OSC_HZ; 911 case HCLK_VOP_ROOT: 912 con = readl(&cru->clksel_con[110]); 913 sel = (con & HCLK_VOP_ROOT_SEL_MASK) >> HCLK_VOP_ROOT_SEL_SHIFT; 914 if (sel == HCLK_VOP_ROOT_SEL_200M) 915 return 200 * MHz; 916 else if (sel == HCLK_VOP_ROOT_SEL_100M) 917 return 100 * MHz; 918 else if (sel == HCLK_VOP_ROOT_SEL_50M) 919 return 50 * MHz; 920 else 921 return OSC_HZ; 922 default: 923 return -ENOENT; 924 } 925 } 926 927 static ulong rk3588_aclk_vop_set_clk(struct rk3588_clk_priv *priv, 928 ulong clk_id, ulong rate) 929 { 930 struct rk3588_cru *cru = priv->cru; 931 int src_clk, div; 932 933 switch (clk_id) { 934 case ACLK_VOP_ROOT: 935 if (!(priv->cpll_hz % rate)) { 936 src_clk = ACLK_VOP_ROOT_SEL_CPLL; 937 div = DIV_ROUND_UP(priv->cpll_hz, rate); 938 } else { 939 src_clk = ACLK_VOP_ROOT_SEL_GPLL; 940 div = DIV_ROUND_UP(priv->gpll_hz, rate); 941 } 942 rk_clrsetreg(&cru->clksel_con[110], 943 ACLK_VOP_ROOT_DIV_MASK | 944 ACLK_VOP_ROOT_SEL_MASK, 945 (src_clk << ACLK_VOP_ROOT_SEL_SHIFT) | 946 (div - 1) << ACLK_VOP_ROOT_DIV_SHIFT); 947 break; 948 case ACLK_VOP_LOW_ROOT: 949 if (rate == 400 * MHz || rate == 396 * MHz) 950 src_clk = ACLK_VOP_LOW_ROOT_SEL_400M; 951 else if (rate == 200 * MHz) 952 src_clk = ACLK_VOP_LOW_ROOT_SEL_200M; 953 else if (rate == 100 * MHz) 954 src_clk = ACLK_VOP_LOW_ROOT_SEL_100M; 955 else 956 src_clk = ACLK_VOP_LOW_ROOT_SEL_24M; 957 rk_clrsetreg(&cru->clksel_con[110], 958 ACLK_VOP_LOW_ROOT_SEL_MASK, 959 src_clk << ACLK_VOP_LOW_ROOT_SEL_SHIFT); 960 break; 961 case HCLK_VOP_ROOT: 962 if (rate == 200 * MHz) 963 src_clk = HCLK_VOP_ROOT_SEL_200M; 964 else if (rate == 100 * MHz) 965 src_clk = HCLK_VOP_ROOT_SEL_100M; 966 else if (rate == 50 * MHz) 967 src_clk = HCLK_VOP_ROOT_SEL_50M; 968 else 969 src_clk = HCLK_VOP_ROOT_SEL_24M; 970 rk_clrsetreg(&cru->clksel_con[110], 971 HCLK_VOP_ROOT_SEL_MASK, 972 src_clk << HCLK_VOP_ROOT_SEL_SHIFT); 973 break; 974 default: 975 return -ENOENT; 976 } 977 978 return rk3588_aclk_vop_get_clk(priv, clk_id); 979 } 980 981 static ulong rk3588_dclk_vop_get_clk(struct rk3588_clk_priv *priv, ulong clk_id) 982 { 983 struct rk3588_cru *cru = priv->cru; 984 u32 div, sel, con, parent; 985 986 switch (clk_id) { 987 case DCLK_VOP0: 988 case DCLK_VOP0_SRC: 989 con = readl(&cru->clksel_con[111]); 990 div = (con & DCLK0_VOP_SRC_DIV_MASK) >> DCLK0_VOP_SRC_DIV_SHIFT; 991 sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT; 992 break; 993 case DCLK_VOP1: 994 case DCLK_VOP1_SRC: 995 con = readl(&cru->clksel_con[111]); 996 div = (con & DCLK1_VOP_SRC_DIV_MASK) >> DCLK1_VOP_SRC_DIV_SHIFT; 997 sel = (con & DCLK1_VOP_SRC_SEL_MASK) >> DCLK1_VOP_SRC_SEL_SHIFT; 998 break; 999 case DCLK_VOP2: 1000 case DCLK_VOP2_SRC: 1001 con = readl(&cru->clksel_con[112]); 1002 div = (con & DCLK2_VOP_SRC_DIV_MASK) >> DCLK2_VOP_SRC_DIV_SHIFT; 1003 sel = (con & DCLK2_VOP_SRC_SEL_MASK) >> DCLK2_VOP_SRC_SEL_SHIFT; 1004 break; 1005 case DCLK_VOP3: 1006 con = readl(&cru->clksel_con[113]); 1007 div = (con & DCLK3_VOP_SRC_DIV_MASK) >> DCLK3_VOP_SRC_DIV_SHIFT; 1008 sel = (con & DCLK3_VOP_SRC_SEL_MASK) >> DCLK3_VOP_SRC_SEL_SHIFT; 1009 break; 1010 default: 1011 return -ENOENT; 1012 } 1013 1014 if (sel == DCLK_VOP_SRC_SEL_AUPLL) 1015 parent = priv->aupll_hz; 1016 else if (sel == DCLK_VOP_SRC_SEL_V0PLL) 1017 parent = rockchip_pll_get_rate(&rk3588_pll_clks[V0PLL], 1018 priv->cru, V0PLL); 1019 else if (sel == DCLK_VOP_SRC_SEL_GPLL) 1020 parent = priv->gpll_hz; 1021 else if (sel == DCLK_VOP_SRC_SEL_CPLL) 1022 parent = priv->cpll_hz; 1023 else 1024 return -ENOENT; 1025 1026 return DIV_TO_RATE(parent, div); 1027 } 1028 1029 #define RK3588_VOP_PLL_LIMIT_FREQ 600000000 1030 1031 static ulong rk3588_dclk_vop_set_clk(struct rk3588_clk_priv *priv, 1032 ulong clk_id, ulong rate) 1033 { 1034 struct rk3588_cru *cru = priv->cru; 1035 ulong pll_rate, now, best_rate = 0; 1036 u32 i, conid, con, sel, div, best_div = 0, best_sel = 0; 1037 u32 mask, div_shift, sel_shift; 1038 1039 switch (clk_id) { 1040 case DCLK_VOP0: 1041 case DCLK_VOP0_SRC: 1042 conid = 111; 1043 con = readl(&cru->clksel_con[111]); 1044 sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT; 1045 mask = DCLK0_VOP_SRC_SEL_MASK | DCLK0_VOP_SRC_DIV_MASK; 1046 div_shift = DCLK0_VOP_SRC_DIV_SHIFT; 1047 sel_shift = DCLK0_VOP_SRC_SEL_SHIFT; 1048 break; 1049 case DCLK_VOP1: 1050 case DCLK_VOP1_SRC: 1051 conid = 111; 1052 con = readl(&cru->clksel_con[111]); 1053 sel = (con & DCLK1_VOP_SRC_SEL_MASK) >> DCLK1_VOP_SRC_SEL_SHIFT; 1054 mask = DCLK1_VOP_SRC_SEL_MASK | DCLK1_VOP_SRC_DIV_MASK; 1055 div_shift = DCLK1_VOP_SRC_DIV_SHIFT; 1056 sel_shift = DCLK1_VOP_SRC_SEL_SHIFT; 1057 break; 1058 case DCLK_VOP2: 1059 case DCLK_VOP2_SRC: 1060 conid = 112; 1061 con = readl(&cru->clksel_con[112]); 1062 sel = (con & DCLK2_VOP_SRC_SEL_MASK) >> DCLK2_VOP_SRC_SEL_SHIFT; 1063 mask = DCLK2_VOP_SRC_SEL_MASK | DCLK2_VOP_SRC_DIV_MASK; 1064 div_shift = DCLK2_VOP_SRC_DIV_SHIFT; 1065 sel_shift = DCLK1_VOP_SRC_SEL_SHIFT; 1066 break; 1067 case DCLK_VOP3: 1068 conid = 113; 1069 con = readl(&cru->clksel_con[113]); 1070 sel = (con & DCLK3_VOP_SRC_SEL_MASK) >> DCLK3_VOP_SRC_SEL_SHIFT; 1071 mask = DCLK2_VOP_SRC_SEL_MASK | DCLK2_VOP_SRC_DIV_MASK; 1072 div_shift = DCLK2_VOP_SRC_DIV_SHIFT; 1073 sel_shift = DCLK1_VOP_SRC_SEL_SHIFT; 1074 break; 1075 default: 1076 return -ENOENT; 1077 } 1078 1079 if (sel == DCLK_VOP_SRC_SEL_V0PLL) { 1080 div = DIV_ROUND_UP(RK3588_VOP_PLL_LIMIT_FREQ, rate); 1081 rk_clrsetreg(&cru->clksel_con[conid], 1082 mask, 1083 ((div - 1) << div_shift)); 1084 rockchip_pll_set_rate(&rk3588_pll_clks[V0PLL], 1085 priv->cru, V0PLL, div * rate); 1086 } else { 1087 for (i = 0; i <= DCLK_VOP_SRC_SEL_AUPLL; i++) { 1088 switch (i) { 1089 case DCLK_VOP_SRC_SEL_GPLL: 1090 pll_rate = priv->gpll_hz; 1091 break; 1092 case DCLK_VOP_SRC_SEL_CPLL: 1093 pll_rate = priv->cpll_hz; 1094 break; 1095 case DCLK_VOP_SRC_SEL_AUPLL: 1096 pll_rate = priv->aupll_hz; 1097 break; 1098 default: 1099 printf("do not support this vop pll sel\n"); 1100 return -EINVAL; 1101 } 1102 1103 div = DIV_ROUND_UP(pll_rate, rate); 1104 if (div > 255) 1105 continue; 1106 now = pll_rate / div; 1107 if (abs(rate - now) < abs(rate - best_rate)) { 1108 best_rate = now; 1109 best_div = div; 1110 best_sel = i; 1111 } 1112 debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n", 1113 pll_rate, best_rate, best_div, best_sel); 1114 } 1115 1116 if (best_rate) { 1117 rk_clrsetreg(&cru->clksel_con[conid], 1118 mask, 1119 best_sel << sel_shift | 1120 (best_div - 1) << div_shift); 1121 } else { 1122 printf("do not support this vop freq %lu\n", rate); 1123 return -EINVAL; 1124 } 1125 } 1126 return rk3588_dclk_vop_get_clk(priv, clk_id); 1127 } 1128 1129 static ulong rk3588_gmac_get_clk(struct rk3588_clk_priv *priv, ulong clk_id) 1130 { 1131 struct rk3588_cru *cru = priv->cru; 1132 u32 con, div; 1133 1134 switch (clk_id) { 1135 case CLK_GMAC0_PTP_REF: 1136 con = readl(&cru->clksel_con[81]); 1137 div = (con & CLK_GMAC0_PTP_DIV_MASK) >> CLK_GMAC0_PTP_DIV_SHIFT; 1138 return DIV_TO_RATE(priv->cpll_hz, div); 1139 case CLK_GMAC1_PTP_REF: 1140 con = readl(&cru->clksel_con[81]); 1141 div = (con & CLK_GMAC1_PTP_DIV_MASK) >> CLK_GMAC1_PTP_DIV_SHIFT; 1142 return DIV_TO_RATE(priv->cpll_hz, div); 1143 case CLK_GMAC_125M: 1144 con = readl(&cru->clksel_con[83]); 1145 div = (con & CLK_GMAC_125M_DIV_MASK) >> CLK_GMAC_125M_DIV_SHIFT; 1146 return DIV_TO_RATE(priv->cpll_hz, div); 1147 case CLK_GMAC_50M: 1148 con = readl(&cru->clksel_con[84]); 1149 div = (con & CLK_GMAC_50M_DIV_MASK) >> CLK_GMAC_50M_DIV_SHIFT; 1150 return DIV_TO_RATE(priv->cpll_hz, div); 1151 default: 1152 return -ENOENT; 1153 } 1154 } 1155 1156 static ulong rk3588_gmac_set_clk(struct rk3588_clk_priv *priv, 1157 ulong clk_id, ulong rate) 1158 { 1159 struct rk3588_cru *cru = priv->cru; 1160 int div; 1161 1162 div = DIV_ROUND_UP(priv->cpll_hz, rate); 1163 1164 switch (clk_id) { 1165 case CLK_GMAC0_PTP_REF: 1166 rk_clrsetreg(&cru->clksel_con[81], 1167 CLK_GMAC0_PTP_DIV_MASK | CLK_GMAC0_PTP_SEL_MASK, 1168 CLK_GMAC0_PTP_SEL_CPLL << CLK_GMAC0_PTP_SEL_SHIFT | 1169 (div - 1) << CLK_GMAC0_PTP_DIV_SHIFT); 1170 break; 1171 case CLK_GMAC1_PTP_REF: 1172 rk_clrsetreg(&cru->clksel_con[81], 1173 CLK_GMAC1_PTP_DIV_MASK | CLK_GMAC1_PTP_SEL_MASK, 1174 CLK_GMAC1_PTP_SEL_CPLL << CLK_GMAC1_PTP_SEL_SHIFT | 1175 (div - 1) << CLK_GMAC1_PTP_DIV_SHIFT); 1176 break; 1177 1178 case CLK_GMAC_125M: 1179 rk_clrsetreg(&cru->clksel_con[83], 1180 CLK_GMAC_125M_DIV_MASK | CLK_GMAC_125M_SEL_MASK, 1181 CLK_GMAC_125M_SEL_CPLL << CLK_GMAC_125M_SEL_SHIFT | 1182 (div - 1) << CLK_GMAC_125M_DIV_SHIFT); 1183 break; 1184 case CLK_GMAC_50M: 1185 rk_clrsetreg(&cru->clksel_con[84], 1186 CLK_GMAC_50M_DIV_MASK | CLK_GMAC_50M_SEL_MASK, 1187 CLK_GMAC_50M_SEL_CPLL << CLK_GMAC_50M_SEL_SHIFT | 1188 (div - 1) << CLK_GMAC_50M_DIV_SHIFT); 1189 break; 1190 default: 1191 return -ENOENT; 1192 } 1193 1194 return rk3588_gmac_get_clk(priv, clk_id); 1195 } 1196 1197 static ulong rk3588_uart_get_rate(struct rk3588_clk_priv *priv, ulong clk_id) 1198 { 1199 struct rk3588_cru *cru = priv->cru; 1200 u32 reg, con, fracdiv, div, src, p_src, p_rate; 1201 unsigned long m, n; 1202 1203 switch (clk_id) { 1204 case SCLK_UART1: 1205 reg = 41; 1206 break; 1207 case SCLK_UART2: 1208 reg = 43; 1209 break; 1210 case SCLK_UART3: 1211 reg = 45; 1212 break; 1213 case SCLK_UART4: 1214 reg = 47; 1215 break; 1216 case SCLK_UART5: 1217 reg = 49; 1218 break; 1219 case SCLK_UART6: 1220 reg = 51; 1221 break; 1222 case SCLK_UART7: 1223 reg = 53; 1224 break; 1225 case SCLK_UART8: 1226 reg = 55; 1227 break; 1228 case SCLK_UART9: 1229 reg = 57; 1230 break; 1231 default: 1232 return -ENOENT; 1233 } 1234 con = readl(&cru->clksel_con[reg + 2]); 1235 src = (con & CLK_UART_SEL_MASK) >> CLK_UART_SEL_SHIFT; 1236 con = readl(&cru->clksel_con[reg]); 1237 div = (con & CLK_UART_SRC_DIV_MASK) >> CLK_UART_SRC_DIV_SHIFT; 1238 p_src = (con & CLK_UART_SRC_SEL_MASK) >> CLK_UART_SRC_SEL_SHIFT; 1239 if (p_src == CLK_UART_SRC_SEL_GPLL) 1240 p_rate = priv->gpll_hz; 1241 else 1242 p_rate = priv->cpll_hz; 1243 1244 if (src == CLK_UART_SEL_SRC) { 1245 return DIV_TO_RATE(p_rate, div); 1246 } else if (src == CLK_UART_SEL_FRAC) { 1247 fracdiv = readl(&cru->clksel_con[reg + 1]); 1248 n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK; 1249 n >>= CLK_UART_FRAC_NUMERATOR_SHIFT; 1250 m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK; 1251 m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT; 1252 return DIV_TO_RATE(p_rate, div) * n / m; 1253 } else { 1254 return OSC_HZ; 1255 } 1256 } 1257 1258 static ulong rk3588_uart_set_rate(struct rk3588_clk_priv *priv, 1259 ulong clk_id, ulong rate) 1260 { 1261 struct rk3588_cru *cru = priv->cru; 1262 u32 reg, clk_src, uart_src, div; 1263 unsigned long m = 0, n = 0, val; 1264 1265 if (priv->gpll_hz % rate == 0) { 1266 clk_src = CLK_UART_SRC_SEL_GPLL; 1267 uart_src = CLK_UART_SEL_SRC; 1268 div = DIV_ROUND_UP(priv->gpll_hz, rate); 1269 } else if (priv->cpll_hz % rate == 0) { 1270 clk_src = CLK_UART_SRC_SEL_CPLL; 1271 uart_src = CLK_UART_SEL_SRC; 1272 div = DIV_ROUND_UP(priv->gpll_hz, rate); 1273 } else if (rate == OSC_HZ) { 1274 clk_src = CLK_UART_SRC_SEL_GPLL; 1275 uart_src = CLK_UART_SEL_XIN24M; 1276 div = 2; 1277 } else { 1278 clk_src = CLK_UART_SRC_SEL_GPLL; 1279 uart_src = CLK_UART_SEL_FRAC; 1280 div = 2; 1281 rational_best_approximation(rate, priv->gpll_hz / div, 1282 GENMASK(16 - 1, 0), 1283 GENMASK(16 - 1, 0), 1284 &m, &n); 1285 } 1286 1287 switch (clk_id) { 1288 case SCLK_UART1: 1289 reg = 41; 1290 break; 1291 case SCLK_UART2: 1292 reg = 43; 1293 break; 1294 case SCLK_UART3: 1295 reg = 45; 1296 break; 1297 case SCLK_UART4: 1298 reg = 47; 1299 break; 1300 case SCLK_UART5: 1301 reg = 49; 1302 break; 1303 case SCLK_UART6: 1304 reg = 51; 1305 break; 1306 case SCLK_UART7: 1307 reg = 53; 1308 break; 1309 case SCLK_UART8: 1310 reg = 55; 1311 break; 1312 case SCLK_UART9: 1313 reg = 57; 1314 break; 1315 default: 1316 return -ENOENT; 1317 } 1318 rk_clrsetreg(&cru->clksel_con[reg], 1319 CLK_UART_SRC_SEL_MASK | 1320 CLK_UART_SRC_DIV_MASK, 1321 (clk_src << CLK_UART_SRC_SEL_SHIFT) | 1322 ((div - 1) << CLK_UART_SRC_DIV_SHIFT)); 1323 rk_clrsetreg(&cru->clksel_con[reg + 2], 1324 CLK_UART_SEL_MASK, 1325 (uart_src << CLK_UART_SEL_SHIFT)); 1326 if (m && n) { 1327 val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n; 1328 writel(val, &cru->clksel_con[reg + 1]); 1329 } 1330 1331 return rk3588_uart_get_rate(priv, clk_id); 1332 } 1333 1334 static ulong rk3588_pciephy_get_rate(struct rk3588_clk_priv *priv, ulong clk_id) 1335 { 1336 struct rk3588_cru *cru = priv->cru; 1337 u32 con, div, src; 1338 1339 switch (clk_id) { 1340 case CLK_REF_PIPE_PHY0: 1341 con = readl(&cru->clksel_con[177]); 1342 src = (con & CLK_PCIE_PHY0_REF_SEL_MASK) >> CLK_PCIE_PHY0_REF_SEL_SHIFT; 1343 con = readl(&cru->clksel_con[176]); 1344 div = (con & CLK_PCIE_PHY0_PLL_DIV_MASK) >> CLK_PCIE_PHY0_PLL_DIV_SHIFT; 1345 break; 1346 case CLK_REF_PIPE_PHY1: 1347 con = readl(&cru->clksel_con[177]); 1348 src = (con & CLK_PCIE_PHY1_REF_SEL_MASK) >> CLK_PCIE_PHY1_REF_SEL_SHIFT; 1349 con = readl(&cru->clksel_con[176]); 1350 div = (con & CLK_PCIE_PHY1_PLL_DIV_MASK) >> CLK_PCIE_PHY1_PLL_DIV_SHIFT; 1351 break; 1352 case CLK_REF_PIPE_PHY2: 1353 con = readl(&cru->clksel_con[177]); 1354 src = (con & CLK_PCIE_PHY2_REF_SEL_MASK) >> CLK_PCIE_PHY2_REF_SEL_SHIFT; 1355 div = (con & CLK_PCIE_PHY2_PLL_DIV_MASK) >> CLK_PCIE_PHY2_PLL_DIV_SHIFT; 1356 break; 1357 default: 1358 return -ENOENT; 1359 } 1360 1361 if (src == CLK_PCIE_PHY_REF_SEL_PPLL) { 1362 return DIV_TO_RATE(priv->ppll_hz, div); 1363 } else { 1364 return OSC_HZ; 1365 } 1366 } 1367 1368 static ulong rk3588_pciephy_set_rate(struct rk3588_clk_priv *priv, 1369 ulong clk_id, ulong rate) 1370 { 1371 struct rk3588_cru *cru = priv->cru; 1372 u32 clk_src, div; 1373 1374 if (rate == OSC_HZ) { 1375 clk_src = CLK_PCIE_PHY_REF_SEL_24M; 1376 div = 1; 1377 } else { 1378 clk_src = CLK_PCIE_PHY_REF_SEL_PPLL; 1379 div = DIV_ROUND_UP(priv->ppll_hz, rate); 1380 } 1381 1382 switch (clk_id) { 1383 case CLK_REF_PIPE_PHY0: 1384 rk_clrsetreg(&cru->clksel_con[177], 1385 CLK_PCIE_PHY0_REF_SEL_MASK, 1386 (clk_src << CLK_PCIE_PHY0_REF_SEL_SHIFT)); 1387 rk_clrsetreg(&cru->clksel_con[176], 1388 CLK_PCIE_PHY0_PLL_DIV_MASK, 1389 ((div - 1) << CLK_PCIE_PHY0_PLL_DIV_SHIFT)); 1390 break; 1391 case CLK_REF_PIPE_PHY1: 1392 rk_clrsetreg(&cru->clksel_con[177], 1393 CLK_PCIE_PHY1_REF_SEL_MASK, 1394 (clk_src << CLK_PCIE_PHY1_REF_SEL_SHIFT)); 1395 rk_clrsetreg(&cru->clksel_con[176], 1396 CLK_PCIE_PHY1_PLL_DIV_MASK, 1397 ((div - 1) << CLK_PCIE_PHY1_PLL_DIV_SHIFT)); 1398 break; 1399 case CLK_REF_PIPE_PHY2: 1400 rk_clrsetreg(&cru->clksel_con[177], 1401 CLK_PCIE_PHY2_REF_SEL_MASK | 1402 CLK_PCIE_PHY2_PLL_DIV_MASK, 1403 (clk_src << CLK_PCIE_PHY2_REF_SEL_SHIFT) | 1404 ((div - 1) << CLK_PCIE_PHY2_PLL_DIV_SHIFT)); 1405 break; 1406 default: 1407 return -ENOENT; 1408 } 1409 1410 return rk3588_pciephy_get_rate(priv, clk_id); 1411 } 1412 #endif 1413 1414 static ulong rk3588_clk_get_rate(struct clk *clk) 1415 { 1416 struct rk3588_clk_priv *priv = dev_get_priv(clk->dev); 1417 ulong rate = 0; 1418 1419 if (!priv->gpll_hz) { 1420 printf("%s gpll=%lu\n", __func__, priv->gpll_hz); 1421 return -ENOENT; 1422 } 1423 1424 if (!priv->ppll_hz) { 1425 priv->ppll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL], 1426 priv->cru, PPLL); 1427 } 1428 1429 switch (clk->id) { 1430 case PLL_LPLL: 1431 rate = rockchip_pll_get_rate(&rk3588_pll_clks[LPLL], priv->cru, 1432 LPLL); 1433 break; 1434 case PLL_B0PLL: 1435 rate = rockchip_pll_get_rate(&rk3588_pll_clks[B0PLL], priv->cru, 1436 B0PLL); 1437 break; 1438 case PLL_B1PLL: 1439 rate = rockchip_pll_get_rate(&rk3588_pll_clks[B1PLL], priv->cru, 1440 B1PLL); 1441 break; 1442 case PLL_GPLL: 1443 rate = rockchip_pll_get_rate(&rk3588_pll_clks[GPLL], priv->cru, 1444 GPLL); 1445 break; 1446 case PLL_CPLL: 1447 rate = rockchip_pll_get_rate(&rk3588_pll_clks[CPLL], priv->cru, 1448 CPLL); 1449 break; 1450 case PLL_NPLL: 1451 rate = rockchip_pll_get_rate(&rk3588_pll_clks[NPLL], priv->cru, 1452 NPLL); 1453 break; 1454 case PLL_V0PLL: 1455 rate = rockchip_pll_get_rate(&rk3588_pll_clks[V0PLL], priv->cru, 1456 V0PLL); 1457 break; 1458 case PLL_AUPLL: 1459 rate = rockchip_pll_get_rate(&rk3588_pll_clks[AUPLL], priv->cru, 1460 AUPLL); 1461 break; 1462 case PLL_PPLL: 1463 rate = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL], priv->cru, 1464 PPLL); 1465 break; 1466 case ACLK_CENTER_ROOT: 1467 case PCLK_CENTER_ROOT: 1468 case HCLK_CENTER_ROOT: 1469 case ACLK_CENTER_LOW_ROOT: 1470 rate = rk3588_center_get_clk(priv, clk->id); 1471 break; 1472 case ACLK_TOP_ROOT: 1473 case PCLK_TOP_ROOT: 1474 case ACLK_LOW_TOP_ROOT: 1475 rate = rk3588_top_get_clk(priv, clk->id); 1476 break; 1477 case CLK_I2C0: 1478 case CLK_I2C1: 1479 case CLK_I2C2: 1480 case CLK_I2C3: 1481 case CLK_I2C4: 1482 case CLK_I2C5: 1483 case CLK_I2C6: 1484 case CLK_I2C7: 1485 case CLK_I2C8: 1486 rate = rk3588_i2c_get_clk(priv, clk->id); 1487 break; 1488 case CLK_SPI0: 1489 case CLK_SPI1: 1490 case CLK_SPI2: 1491 case CLK_SPI3: 1492 case CLK_SPI4: 1493 rate = rk3588_spi_get_clk(priv, clk->id); 1494 break; 1495 case CLK_PWM1: 1496 case CLK_PWM2: 1497 case CLK_PWM3: 1498 rate = rk3588_pwm_get_clk(priv, clk->id); 1499 break; 1500 case CLK_SARADC: 1501 case CLK_TSADC: 1502 rate = rk3588_adc_get_clk(priv, clk->id); 1503 break; 1504 case CCLK_SRC_SDIO: 1505 case CCLK_EMMC: 1506 case BCLK_EMMC: 1507 case SCLK_SFC: 1508 case DCLK_DECOM: 1509 rate = rk3588_mmc_get_clk(priv, clk->id); 1510 break; 1511 #ifndef CONFIG_SPL_BUILD 1512 case ACLK_VOP_ROOT: 1513 case ACLK_VOP_LOW_ROOT: 1514 case HCLK_VOP_ROOT: 1515 rate = rk3588_aclk_vop_get_clk(priv, clk->id); 1516 break; 1517 case DCLK_VOP0: 1518 case DCLK_VOP0_SRC: 1519 case DCLK_VOP1: 1520 case DCLK_VOP1_SRC: 1521 case DCLK_VOP2: 1522 case DCLK_VOP2_SRC: 1523 case DCLK_VOP3: 1524 rate = rk3588_dclk_vop_get_clk(priv, clk->id); 1525 break; 1526 case CLK_GMAC0_PTP_REF: 1527 case CLK_GMAC1_PTP_REF: 1528 case CLK_GMAC_125M: 1529 case CLK_GMAC_50M: 1530 rate = rk3588_gmac_get_clk(priv, clk->id); 1531 break; 1532 case SCLK_UART1: 1533 case SCLK_UART2: 1534 case SCLK_UART3: 1535 case SCLK_UART4: 1536 case SCLK_UART5: 1537 case SCLK_UART6: 1538 case SCLK_UART7: 1539 case SCLK_UART8: 1540 case SCLK_UART9: 1541 rate = rk3588_uart_get_rate(priv, clk->id); 1542 break; 1543 case CLK_REF_PIPE_PHY0: 1544 case CLK_REF_PIPE_PHY1: 1545 case CLK_REF_PIPE_PHY2: 1546 rate = rk3588_pciephy_get_rate(priv, clk->id); 1547 break; 1548 #endif 1549 default: 1550 return -ENOENT; 1551 } 1552 1553 return rate; 1554 }; 1555 1556 static ulong rk3588_clk_set_rate(struct clk *clk, ulong rate) 1557 { 1558 struct rk3588_clk_priv *priv = dev_get_priv(clk->dev); 1559 ulong ret = 0; 1560 1561 if (!priv->gpll_hz) { 1562 printf("%s gpll=%lu\n", __func__, priv->gpll_hz); 1563 return -ENOENT; 1564 } 1565 1566 if (!priv->ppll_hz) { 1567 priv->ppll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL], 1568 priv->cru, PPLL); 1569 } 1570 1571 switch (clk->id) { 1572 case PLL_CPLL: 1573 ret = rockchip_pll_set_rate(&rk3588_pll_clks[CPLL], priv->cru, 1574 CPLL, rate); 1575 priv->cpll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[CPLL], 1576 priv->cru, CPLL); 1577 break; 1578 case PLL_GPLL: 1579 ret = rockchip_pll_set_rate(&rk3588_pll_clks[GPLL], priv->cru, 1580 GPLL, rate); 1581 priv->gpll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[GPLL], 1582 priv->cru, GPLL); 1583 break; 1584 case PLL_NPLL: 1585 ret = rockchip_pll_set_rate(&rk3588_pll_clks[NPLL], priv->cru, 1586 NPLL, rate); 1587 break; 1588 case PLL_V0PLL: 1589 ret = rockchip_pll_set_rate(&rk3588_pll_clks[V0PLL], priv->cru, 1590 V0PLL, rate); 1591 priv->v0pll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[V0PLL], 1592 priv->cru, V0PLL); 1593 break; 1594 case PLL_AUPLL: 1595 ret = rockchip_pll_set_rate(&rk3588_pll_clks[AUPLL], priv->cru, 1596 AUPLL, rate); 1597 priv->aupll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[AUPLL], 1598 priv->cru, AUPLL); 1599 break; 1600 case PLL_PPLL: 1601 ret = rockchip_pll_set_rate(&rk3588_pll_clks[PPLL], priv->cru, 1602 PPLL, rate); 1603 priv->ppll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL], 1604 priv->cru, PPLL); 1605 break; 1606 case ACLK_CENTER_ROOT: 1607 case PCLK_CENTER_ROOT: 1608 case HCLK_CENTER_ROOT: 1609 case ACLK_CENTER_LOW_ROOT: 1610 ret = rk3588_center_set_clk(priv, clk->id, rate); 1611 break; 1612 case ACLK_TOP_ROOT: 1613 case PCLK_TOP_ROOT: 1614 case ACLK_LOW_TOP_ROOT: 1615 ret = rk3588_top_set_clk(priv, clk->id, rate); 1616 break; 1617 case CLK_I2C0: 1618 case CLK_I2C1: 1619 case CLK_I2C2: 1620 case CLK_I2C3: 1621 case CLK_I2C4: 1622 case CLK_I2C5: 1623 case CLK_I2C6: 1624 case CLK_I2C7: 1625 case CLK_I2C8: 1626 ret = rk3588_i2c_set_clk(priv, clk->id, rate); 1627 break; 1628 case CLK_SPI0: 1629 case CLK_SPI1: 1630 case CLK_SPI2: 1631 case CLK_SPI3: 1632 case CLK_SPI4: 1633 ret = rk3588_spi_set_clk(priv, clk->id, rate); 1634 break; 1635 case CLK_PWM1: 1636 case CLK_PWM2: 1637 case CLK_PWM3: 1638 ret = rk3588_pwm_set_clk(priv, clk->id, rate); 1639 break; 1640 case CLK_SARADC: 1641 case CLK_TSADC: 1642 ret = rk3588_adc_set_clk(priv, clk->id, rate); 1643 break; 1644 case CCLK_SRC_SDIO: 1645 case CCLK_EMMC: 1646 case BCLK_EMMC: 1647 case SCLK_SFC: 1648 case DCLK_DECOM: 1649 ret = rk3588_mmc_set_clk(priv, clk->id, rate); 1650 break; 1651 #ifndef CONFIG_SPL_BUILD 1652 case ACLK_VOP_ROOT: 1653 case ACLK_VOP_LOW_ROOT: 1654 case HCLK_VOP_ROOT: 1655 ret = rk3588_aclk_vop_set_clk(priv, clk->id, rate); 1656 break; 1657 case DCLK_VOP0: 1658 case DCLK_VOP0_SRC: 1659 case DCLK_VOP1: 1660 case DCLK_VOP1_SRC: 1661 case DCLK_VOP2: 1662 case DCLK_VOP2_SRC: 1663 case DCLK_VOP3: 1664 ret = rk3588_dclk_vop_set_clk(priv, clk->id, rate); 1665 break; 1666 case CLK_GMAC0_PTP_REF: 1667 case CLK_GMAC1_PTP_REF: 1668 case CLK_GMAC_125M: 1669 case CLK_GMAC_50M: 1670 ret = rk3588_gmac_set_clk(priv, clk->id, rate); 1671 break; 1672 case SCLK_UART1: 1673 case SCLK_UART2: 1674 case SCLK_UART3: 1675 case SCLK_UART4: 1676 case SCLK_UART5: 1677 case SCLK_UART6: 1678 case SCLK_UART7: 1679 case SCLK_UART8: 1680 case SCLK_UART9: 1681 ret = rk3588_uart_set_rate(priv, clk->id, rate); 1682 break; 1683 case CLK_REF_PIPE_PHY0: 1684 case CLK_REF_PIPE_PHY1: 1685 case CLK_REF_PIPE_PHY2: 1686 ret = rk3588_pciephy_set_rate(priv, clk->id, rate); 1687 break; 1688 #endif 1689 default: 1690 return -ENOENT; 1691 } 1692 1693 return ret; 1694 }; 1695 1696 #define ROCKCHIP_MMC_DELAY_SEL BIT(10) 1697 #define ROCKCHIP_MMC_DEGREE_MASK 0x3 1698 #define ROCKCHIP_MMC_DELAYNUM_OFFSET 2 1699 #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET) 1700 1701 #define PSECS_PER_SEC 1000000000000LL 1702 /* 1703 * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to 1704 * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg. 1705 */ 1706 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60 1707 1708 int rk3588_mmc_get_phase(struct clk *clk) 1709 { 1710 struct rk3588_clk_priv *priv = dev_get_priv(clk->dev); 1711 struct rk3588_cru *cru = priv->cru; 1712 u32 raw_value, delay_num; 1713 u16 degrees = 0; 1714 ulong rate; 1715 1716 rate = rk3588_clk_get_rate(clk); 1717 if (rate < 0) 1718 return rate; 1719 1720 if (clk->id == SCLK_SDMMC_SAMPLE) 1721 raw_value = readl(&cru->sdmmc_con[1]); 1722 else 1723 return 0; 1724 1725 raw_value >>= 1; 1726 degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90; 1727 1728 if (raw_value & ROCKCHIP_MMC_DELAY_SEL) { 1729 /* degrees/delaynum * 10000 */ 1730 unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) * 1731 36 * (rate / 1000000); 1732 1733 delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK); 1734 delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET; 1735 degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000); 1736 } 1737 1738 return degrees % 360; 1739 } 1740 1741 int rk3588_mmc_set_phase(struct clk *clk, u32 degrees) 1742 { 1743 struct rk3588_clk_priv *priv = dev_get_priv(clk->dev); 1744 struct rk3588_cru *cru = priv->cru; 1745 u8 nineties, remainder, delay_num; 1746 u32 raw_value, delay; 1747 ulong rate; 1748 1749 rate = rk3588_clk_get_rate(clk); 1750 if (rate < 0) 1751 return rate; 1752 1753 nineties = degrees / 90; 1754 remainder = (degrees % 90); 1755 1756 /* 1757 * Convert to delay; do a little extra work to make sure we 1758 * don't overflow 32-bit / 64-bit numbers. 1759 */ 1760 delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */ 1761 delay *= remainder; 1762 delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 * 1763 (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10)); 1764 1765 delay_num = (u8)min_t(u32, delay, 255); 1766 1767 raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0; 1768 raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET; 1769 raw_value |= nineties; 1770 1771 raw_value <<= 1; 1772 if (clk->id == SCLK_SDMMC_SAMPLE) 1773 writel(raw_value | 0xffff0000, &cru->sdmmc_con[1]); 1774 1775 debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n", 1776 degrees, delay_num, raw_value, rk3588_mmc_get_phase(clk)); 1777 1778 return 0; 1779 } 1780 1781 static int rk3588_clk_get_phase(struct clk *clk) 1782 { 1783 int ret; 1784 1785 debug("%s %ld\n", __func__, clk->id); 1786 switch (clk->id) { 1787 case SCLK_SDMMC_SAMPLE: 1788 ret = rk3588_mmc_get_phase(clk); 1789 break; 1790 default: 1791 return -ENOENT; 1792 } 1793 1794 return ret; 1795 } 1796 1797 static int rk3588_clk_set_phase(struct clk *clk, int degrees) 1798 { 1799 int ret; 1800 1801 debug("%s %ld\n", __func__, clk->id); 1802 switch (clk->id) { 1803 case SCLK_SDMMC_SAMPLE: 1804 ret = rk3588_mmc_set_phase(clk, degrees); 1805 break; 1806 default: 1807 return -ENOENT; 1808 } 1809 1810 return ret; 1811 } 1812 1813 #if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA)) 1814 static int __maybe_unused rk3588_dclk_vop_set_parent(struct clk *clk, 1815 struct clk *parent) 1816 { 1817 struct rk3588_clk_priv *priv = dev_get_priv(clk->dev); 1818 struct rk3588_cru *cru = priv->cru; 1819 u32 sel; 1820 1821 if (parent->id == PLL_V0PLL) 1822 sel = 2; 1823 else if (parent->id == PLL_GPLL) 1824 sel = 0; 1825 else if (parent->id == PLL_CPLL) 1826 sel = 1; 1827 else 1828 sel = 3; 1829 1830 switch (clk->id) { 1831 case DCLK_VOP0_SRC: 1832 rk_clrsetreg(&cru->clksel_con[111], DCLK0_VOP_SRC_SEL_MASK, 1833 sel << DCLK0_VOP_SRC_SEL_SHIFT); 1834 break; 1835 case DCLK_VOP1_SRC: 1836 rk_clrsetreg(&cru->clksel_con[111], DCLK1_VOP_SRC_SEL_MASK, 1837 sel << DCLK1_VOP_SRC_SEL_SHIFT); 1838 break; 1839 case DCLK_VOP2_SRC: 1840 rk_clrsetreg(&cru->clksel_con[112], DCLK2_VOP_SRC_SEL_MASK, 1841 sel << DCLK2_VOP_SRC_SEL_SHIFT); 1842 break; 1843 case DCLK_VOP3: 1844 rk_clrsetreg(&cru->clksel_con[113], DCLK3_VOP_SRC_SEL_MASK, 1845 sel << DCLK3_VOP_SRC_SEL_SHIFT); 1846 break; 1847 default: 1848 return -EINVAL; 1849 } 1850 return 0; 1851 } 1852 1853 static int rk3588_clk_set_parent(struct clk *clk, struct clk *parent) 1854 { 1855 switch (clk->id) { 1856 case DCLK_VOP0_SRC: 1857 case DCLK_VOP1_SRC: 1858 case DCLK_VOP2_SRC: 1859 case DCLK_VOP3: 1860 return rk3588_dclk_vop_set_parent(clk, parent); 1861 default: 1862 return -ENOENT; 1863 } 1864 1865 return 0; 1866 } 1867 #endif 1868 1869 static struct clk_ops rk3588_clk_ops = { 1870 .get_rate = rk3588_clk_get_rate, 1871 .set_rate = rk3588_clk_set_rate, 1872 .get_phase = rk3588_clk_get_phase, 1873 .set_phase = rk3588_clk_set_phase, 1874 #if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA)) 1875 .set_parent = rk3588_clk_set_parent, 1876 #endif 1877 }; 1878 1879 static void rk3588_clk_init(struct rk3588_clk_priv *priv) 1880 { 1881 int ret, div; 1882 1883 priv->sync_kernel = false; 1884 if (!priv->armclk_enter_hz) { 1885 ret = rockchip_pll_set_rate(&rk3588_pll_clks[LPLL], priv->cru, 1886 LPLL, LPLL_HZ); 1887 priv->armclk_enter_hz = 1888 rockchip_pll_get_rate(&rk3588_pll_clks[LPLL], 1889 priv->cru, LPLL); 1890 priv->armclk_init_hz = priv->armclk_enter_hz; 1891 ret = rockchip_pll_set_rate(&rk3588_pll_clks[B0PLL], priv->cru, 1892 B0PLL, LPLL_HZ); 1893 ret = rockchip_pll_set_rate(&rk3588_pll_clks[B1PLL], priv->cru, 1894 B1PLL, LPLL_HZ); 1895 } 1896 1897 div = DIV_ROUND_UP(GPLL_HZ, 300 * MHz); 1898 rk_clrsetreg(&priv->cru->clksel_con[38], 1899 ACLK_BUS_ROOT_SEL_MASK | 1900 ACLK_BUS_ROOT_DIV_MASK, 1901 div << ACLK_BUS_ROOT_DIV_SHIFT); 1902 1903 if (priv->cpll_hz != CPLL_HZ) { 1904 ret = rockchip_pll_set_rate(&rk3588_pll_clks[CPLL], priv->cru, 1905 CPLL, CPLL_HZ); 1906 if (!ret) 1907 priv->cpll_hz = CPLL_HZ; 1908 } 1909 if (priv->gpll_hz != GPLL_HZ) { 1910 ret = rockchip_pll_set_rate(&rk3588_pll_clks[GPLL], priv->cru, 1911 GPLL, GPLL_HZ); 1912 if (!ret) 1913 priv->gpll_hz = GPLL_HZ; 1914 } 1915 1916 rk_clrsetreg(&priv->cru->clksel_con[9], 1917 ACLK_TOP_S400_SEL_MASK | 1918 ACLK_TOP_S200_SEL_MASK, 1919 (ACLK_TOP_S400_SEL_400M << ACLK_TOP_S400_SEL_SHIFT) | 1920 (ACLK_TOP_S200_SEL_200M << ACLK_TOP_S200_SEL_SHIFT)); 1921 } 1922 1923 static int rk3588_clk_probe(struct udevice *dev) 1924 { 1925 struct rk3588_clk_priv *priv = dev_get_priv(dev); 1926 int ret; 1927 struct clk clk; 1928 1929 ret = rockchip_get_scmi_clk(&clk.dev); 1930 if (ret) { 1931 printf("Failed to get scmi clk dev\n"); 1932 return ret; 1933 } 1934 clk.id = SCMI_SPLL; 1935 ret = clk_set_rate(&clk, 702000000); 1936 if (ret < 0) { 1937 printf("Failed to set spll\n"); 1938 } 1939 1940 priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 1941 if (IS_ERR(priv->grf)) 1942 return PTR_ERR(priv->grf); 1943 1944 rk3588_clk_init(priv); 1945 1946 /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */ 1947 ret = clk_set_defaults(dev); 1948 if (ret) 1949 debug("%s clk_set_defaults failed %d\n", __func__, ret); 1950 else 1951 priv->sync_kernel = true; 1952 1953 return 0; 1954 } 1955 1956 static int rk3588_clk_ofdata_to_platdata(struct udevice *dev) 1957 { 1958 struct rk3588_clk_priv *priv = dev_get_priv(dev); 1959 1960 priv->cru = dev_read_addr_ptr(dev); 1961 1962 return 0; 1963 } 1964 1965 static int rk3588_clk_bind(struct udevice *dev) 1966 { 1967 int ret; 1968 struct udevice *sys_child, *sf_child; 1969 struct sysreset_reg *priv; 1970 struct softreset_reg *sf_priv; 1971 1972 /* The reset driver does not have a device node, so bind it here */ 1973 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset", 1974 &sys_child); 1975 if (ret) { 1976 debug("Warning: No sysreset driver: ret=%d\n", ret); 1977 } else { 1978 priv = malloc(sizeof(struct sysreset_reg)); 1979 priv->glb_srst_fst_value = offsetof(struct rk3588_cru, 1980 glb_srst_fst); 1981 priv->glb_srst_snd_value = offsetof(struct rk3588_cru, 1982 glb_srsr_snd); 1983 sys_child->priv = priv; 1984 } 1985 1986 ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset", 1987 dev_ofnode(dev), &sf_child); 1988 if (ret) { 1989 debug("Warning: No rockchip reset driver: ret=%d\n", ret); 1990 } else { 1991 sf_priv = malloc(sizeof(struct softreset_reg)); 1992 sf_priv->sf_reset_offset = offsetof(struct rk3588_cru, 1993 softrst_con[0]); 1994 sf_priv->sf_reset_num = 49158; 1995 sf_child->priv = sf_priv; 1996 } 1997 1998 return 0; 1999 } 2000 2001 static const struct udevice_id rk3588_clk_ids[] = { 2002 { .compatible = "rockchip,rk3588-cru" }, 2003 { } 2004 }; 2005 2006 U_BOOT_DRIVER(rockchip_rk3588_cru) = { 2007 .name = "rockchip_rk3588_cru", 2008 .id = UCLASS_CLK, 2009 .of_match = rk3588_clk_ids, 2010 .priv_auto_alloc_size = sizeof(struct rk3588_clk_priv), 2011 .ofdata_to_platdata = rk3588_clk_ofdata_to_platdata, 2012 .ops = &rk3588_clk_ops, 2013 .bind = rk3588_clk_bind, 2014 .probe = rk3588_clk_probe, 2015 }; 2016 2017 #ifdef CONFIG_SPL_BUILD 2018 #define SCRU_BASE 0xfd7d0000 2019 #define BUSSCRU_BASE 0xfd7d8000 2020 #define GPLL_RATE 1188000000 2021 #define SPLL_RATE 702000000 2022 2023 #ifndef BITS_WITH_WMASK 2024 #define BITS_WITH_WMASK(bits, msk, shift) \ 2025 ((bits) << (shift)) | ((msk) << ((shift) + 16)) 2026 #endif 2027 2028 #define CLKDIV_6BITS_SHF(div, shift) BITS_WITH_WMASK(div, 0x3fU, shift) 2029 #define CLKDIV_5BITS_SHF(div, shift) BITS_WITH_WMASK(div, 0x1fU, shift) 2030 2031 static ulong rk3588_clk_scmi_get_rate(struct clk *clk) 2032 { 2033 u32 src, div; 2034 2035 switch (clk->id) { 2036 case SCMI_SPLL: 2037 src = readl(BUSSCRU_BASE + RK3588_MODE_CON0) & 0x3; 2038 if (src == 0) 2039 return OSC_HZ; 2040 else if (src == 1) 2041 return 702 * MHz; 2042 else 2043 return 32768; 2044 case SCMI_CCLK_SD: 2045 src = readl(SCRU_BASE + RK3588_CLKSEL_CON(3)) & 0x3000; 2046 src = src >> 12; 2047 div = readl(SCRU_BASE + RK3588_CLKSEL_CON(3)) & 0x0fc0; 2048 div = div >> 6; 2049 if (src == 1) 2050 return SPLL_RATE / (div + 1); 2051 else if (src == 2) 2052 return OSC_HZ / (div + 1); 2053 else 2054 return GPLL_RATE / (div + 1); 2055 case SCMI_DCLK_SD: 2056 src = readl(SCRU_BASE + RK3588_CLKSEL_CON(3)) & 0x0020; 2057 div = readl(SCRU_BASE + RK3588_CLKSEL_CON(3)) & 0x001f; 2058 if (src) 2059 return SPLL_RATE / (div + 1); 2060 else 2061 return GPLL_RATE / (div + 1); 2062 case SCMI_CRYPTO_RNG: 2063 src = readl(SCRU_BASE + RK3588_CLKSEL_CON(1)) & 0xc000; 2064 src = src >> 14; 2065 if (src == 0) 2066 return 175 * MHz; 2067 else if (src == 1) 2068 return 116 * MHz; 2069 else if (src == 2) 2070 return 58 * MHz; 2071 else 2072 return OSC_HZ; 2073 case SCMI_CRYPTO_CORE: 2074 src = readl(SCRU_BASE + RK3588_CLKSEL_CON(1)) & 0x0c00; 2075 src = src >> 10; 2076 if (src == 0) 2077 return 350 * MHz; 2078 else if (src == 1) 2079 return 233 * MHz; 2080 else if (src == 2) 2081 return 116 * MHz; 2082 else 2083 return OSC_HZ; 2084 case SCMI_CRYPTO_PKA: 2085 src = readl(SCRU_BASE + RK3588_CLKSEL_CON(1)) & 0x3000; 2086 src = src >> 12; 2087 if (src == 0) 2088 return 350 * MHz; 2089 else if (src == 1) 2090 return 233 * MHz; 2091 else if (src == 2) 2092 return 116 * MHz; 2093 else 2094 return OSC_HZ; 2095 case SCMI_KEYLADDER_CORE: 2096 src = readl(SCRU_BASE + RK3588_CLKSEL_CON(2)) & 0x00c0; 2097 src = src >> 6; 2098 if (src == 0) 2099 return 350 * MHz; 2100 else if (src == 1) 2101 return 233 * MHz; 2102 else if (src == 2) 2103 return 116 * MHz; 2104 else 2105 return OSC_HZ; 2106 case SCMI_KEYLADDER_RNG: 2107 src = readl(SCRU_BASE + RK3588_CLKSEL_CON(2)) & 0x0300; 2108 src = src >> 8; 2109 if (src == 0) 2110 return 175 * MHz; 2111 else if (src == 1) 2112 return 116 * MHz; 2113 else if (src == 2) 2114 return 58 * MHz; 2115 else 2116 return OSC_HZ; 2117 case SCMI_TCLK_WDT: 2118 return OSC_HZ; 2119 case SCMI_HCLK_SD: 2120 case SCMI_HCLK_SECURE_NS: 2121 src = readl(SCRU_BASE + RK3588_CLKSEL_CON(1)) & 0x000c; 2122 src = src >> 2; 2123 if (src == 0) 2124 return 150 * MHz; 2125 else if (src == 1) 2126 return 100 * MHz; 2127 else if (src == 2) 2128 return 50 * MHz; 2129 else 2130 return OSC_HZ; 2131 default: 2132 return -ENOENT; 2133 } 2134 }; 2135 2136 static ulong rk3588_clk_scmi_set_rate(struct clk *clk, ulong rate) 2137 { 2138 u32 src, div; 2139 2140 if ((readl(BUSSCRU_BASE + RK3588_PLL_CON(137)) & 0x01c0) == 0xc0) { 2141 writel(BITS_WITH_WMASK(0, 0x3U, 0), 2142 BUSSCRU_BASE + RK3588_MODE_CON0); 2143 writel(BITS_WITH_WMASK(2, 0x7U, 6), 2144 BUSSCRU_BASE + RK3588_PLL_CON(137)); 2145 writel(BITS_WITH_WMASK(1, 0x3U, 0), 2146 BUSSCRU_BASE + RK3588_MODE_CON0); 2147 } 2148 2149 switch (clk->id) { 2150 case SCMI_SPLL: 2151 if (rate >= 700 * MHz) 2152 src = 1; 2153 else 2154 src = 0; 2155 writel(BITS_WITH_WMASK(0, 0x3U, 0), 2156 BUSSCRU_BASE + RK3588_MODE_CON0); 2157 writel(BITS_WITH_WMASK(2, 0x7U, 6), 2158 BUSSCRU_BASE + RK3588_PLL_CON(137)); 2159 writel(BITS_WITH_WMASK(src, 0x3U, 0), 2160 BUSSCRU_BASE + RK3588_MODE_CON0); 2161 break; 2162 case SCMI_CCLK_SD: 2163 if ((OSC_HZ % rate) == 0) { 2164 div = DIV_ROUND_UP(OSC_HZ, rate); 2165 writel(CLKDIV_6BITS_SHF(div - 1, 6) | 2166 BITS_WITH_WMASK(2U, 0x3U, 12), 2167 SCRU_BASE + RK3588_CLKSEL_CON(3)); 2168 } else if ((SPLL_RATE % rate) == 0) { 2169 div = DIV_ROUND_UP(SPLL_RATE, rate); 2170 writel(CLKDIV_6BITS_SHF(div - 1, 6) | 2171 BITS_WITH_WMASK(1U, 0x3U, 12), 2172 SCRU_BASE + RK3588_CLKSEL_CON(3)); 2173 } else { 2174 div = DIV_ROUND_UP(GPLL_RATE, rate); 2175 writel(CLKDIV_6BITS_SHF(div - 1, 6) | 2176 BITS_WITH_WMASK(0U, 0x3U, 12), 2177 SCRU_BASE + RK3588_CLKSEL_CON(3)); 2178 } 2179 break; 2180 case SCMI_DCLK_SD: 2181 if ((SPLL_RATE % rate) == 0) { 2182 div = DIV_ROUND_UP(SPLL_RATE, rate); 2183 writel(CLKDIV_5BITS_SHF(div - 1, 0) | 2184 BITS_WITH_WMASK(1U, 0x1U, 5), 2185 SCRU_BASE + RK3588_CLKSEL_CON(3)); 2186 } else { 2187 div = DIV_ROUND_UP(GPLL_RATE, rate); 2188 writel(CLKDIV_5BITS_SHF(div - 1, 0) | 2189 BITS_WITH_WMASK(0U, 0x1U, 5), 2190 SCRU_BASE + RK3588_CLKSEL_CON(3)); 2191 } 2192 break; 2193 case SCMI_CRYPTO_RNG: 2194 if (rate >= 175 * MHz) 2195 src = 0; 2196 else if (rate >= 116 * MHz) 2197 src = 1; 2198 else if (rate >= 58 * MHz) 2199 src = 2; 2200 else 2201 src = 3; 2202 2203 writel(BITS_WITH_WMASK(src, 0x3U, 14), 2204 SCRU_BASE + RK3588_CLKSEL_CON(1)); 2205 break; 2206 case SCMI_CRYPTO_CORE: 2207 if (rate >= 350 * MHz) 2208 src = 0; 2209 else if (rate >= 233 * MHz) 2210 src = 1; 2211 else if (rate >= 116 * MHz) 2212 src = 2; 2213 else 2214 src = 3; 2215 2216 writel(BITS_WITH_WMASK(src, 0x3U, 10), 2217 SCRU_BASE + RK3588_CLKSEL_CON(1)); 2218 break; 2219 case SCMI_CRYPTO_PKA: 2220 if (rate >= 350 * MHz) 2221 src = 0; 2222 else if (rate >= 233 * MHz) 2223 src = 1; 2224 else if (rate >= 116 * MHz) 2225 src = 2; 2226 else 2227 src = 3; 2228 2229 writel(BITS_WITH_WMASK(src, 0x3U, 12), 2230 SCRU_BASE + RK3588_CLKSEL_CON(1)); 2231 break; 2232 case SCMI_KEYLADDER_CORE: 2233 if (rate >= 350 * MHz) 2234 src = 0; 2235 else if (rate >= 233 * MHz) 2236 src = 1; 2237 else if (rate >= 116 * MHz) 2238 src = 2; 2239 else 2240 src = 3; 2241 2242 writel(BITS_WITH_WMASK(src, 0x3U, 6), 2243 SCRU_BASE + RK3588_CLKSEL_CON(2)); 2244 break; 2245 case SCMI_KEYLADDER_RNG: 2246 if (rate >= 175 * MHz) 2247 src = 0; 2248 else if (rate >= 116 * MHz) 2249 src = 1; 2250 else if (rate >= 58 * MHz) 2251 src = 2; 2252 else 2253 src = 3; 2254 2255 writel(BITS_WITH_WMASK(src, 0x3U, 8), 2256 SCRU_BASE + RK3588_CLKSEL_CON(2)); 2257 break; 2258 case SCMI_TCLK_WDT: 2259 break; 2260 case SCMI_HCLK_SD: 2261 case SCMI_HCLK_SECURE_NS: 2262 if (rate >= 150 * MHz) 2263 src = 0; 2264 else if (rate >= 100 * MHz) 2265 src = 1; 2266 else if (rate >= 50 * MHz) 2267 src = 2; 2268 else 2269 src = 3; 2270 writel(BITS_WITH_WMASK(src, 0x3U, 2), 2271 SCRU_BASE + RK3588_CLKSEL_CON(1)); 2272 break; 2273 default: 2274 return -ENOENT; 2275 } 2276 return 0; 2277 }; 2278 2279 /* A fake scmi driver for SPL/TPL where smccc agent is not available. */ 2280 static const struct clk_ops scmi_clk_ops = { 2281 .get_rate = rk3588_clk_scmi_get_rate, 2282 .set_rate = rk3588_clk_scmi_set_rate, 2283 }; 2284 2285 U_BOOT_DRIVER(scmi_clock) = { 2286 .name = "scmi_clk", 2287 .id = UCLASS_CLK, 2288 .ops = &scmi_clk_ops, 2289 }; 2290 #endif 2291 2292 #ifndef CONFIG_SPL_BUILD 2293 /** 2294 * soc_clk_dump() - Print clock frequencies 2295 * Returns zero on success 2296 * 2297 * Implementation for the clk dump command. 2298 */ 2299 int soc_clk_dump(void) 2300 { 2301 struct udevice *cru_dev; 2302 struct rk3588_clk_priv *priv; 2303 const struct rk3588_clk_info *clk_dump; 2304 struct clk clk; 2305 unsigned long clk_count = ARRAY_SIZE(clks_dump); 2306 unsigned long rate; 2307 int i, ret; 2308 2309 ret = uclass_get_device_by_driver(UCLASS_CLK, 2310 DM_GET_DRIVER(rockchip_rk3588_cru), 2311 &cru_dev); 2312 if (ret) { 2313 printf("%s failed to get cru device\n", __func__); 2314 return ret; 2315 } 2316 2317 priv = dev_get_priv(cru_dev); 2318 printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n", 2319 priv->sync_kernel ? "sync kernel" : "uboot", 2320 priv->armclk_enter_hz / 1000, 2321 priv->armclk_init_hz / 1000, 2322 priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0, 2323 priv->set_armclk_rate ? " KHz" : "N/A"); 2324 for (i = 0; i < clk_count; i++) { 2325 clk_dump = &clks_dump[i]; 2326 if (clk_dump->name) { 2327 clk.id = clk_dump->id; 2328 if (clk_dump->is_cru) 2329 ret = clk_request(cru_dev, &clk); 2330 if (ret < 0) 2331 return ret; 2332 2333 rate = clk_get_rate(&clk); 2334 clk_free(&clk); 2335 if (i == 0) { 2336 if (rate < 0) 2337 printf(" %s %s\n", clk_dump->name, 2338 "unknown"); 2339 else 2340 printf(" %s %lu KHz\n", clk_dump->name, 2341 rate / 1000); 2342 } else { 2343 if (rate < 0) 2344 printf(" %s %s\n", clk_dump->name, 2345 "unknown"); 2346 else 2347 printf(" %s %lu KHz\n", clk_dump->name, 2348 rate / 1000); 2349 } 2350 } 2351 } 2352 2353 return 0; 2354 } 2355 #endif 2356