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