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_PWM1_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_aux16m_get_clk(struct rk3588_clk_priv *priv, ulong clk_id) 890 { 891 struct rk3588_cru *cru = priv->cru; 892 u32 div, con, parent; 893 894 parent = priv->gpll_hz; 895 con = readl(&cru->clksel_con[117]); 896 897 switch (clk_id) { 898 case CLK_AUX16M_0: 899 div = (con & CLK_AUX16MHZ_0_DIV_MASK) >> CLK_AUX16MHZ_0_DIV_SHIFT; 900 return DIV_TO_RATE(parent, div); 901 case CLK_AUX16M_1: 902 div = (con & CLK_AUX16MHZ_1_DIV_MASK) >> CLK_AUX16MHZ_1_DIV_SHIFT; 903 return DIV_TO_RATE(parent, div); 904 default: 905 return -ENOENT; 906 } 907 } 908 909 static ulong rk3588_aux16m_set_clk(struct rk3588_clk_priv *priv, 910 ulong clk_id, ulong rate) 911 { 912 struct rk3588_cru *cru = priv->cru; 913 u32 div; 914 915 if (!priv->gpll_hz) { 916 printf("%s gpll=%lu\n", __func__, priv->gpll_hz); 917 return -ENOENT; 918 } 919 920 div = DIV_ROUND_UP(priv->gpll_hz, rate); 921 922 switch (clk_id) { 923 case CLK_AUX16M_0: 924 rk_clrsetreg(&cru->clksel_con[117], CLK_AUX16MHZ_0_DIV_MASK, 925 (div - 1) << CLK_AUX16MHZ_0_DIV_SHIFT); 926 break; 927 case CLK_AUX16M_1: 928 rk_clrsetreg(&cru->clksel_con[117], CLK_AUX16MHZ_1_DIV_MASK, 929 (div - 1) << CLK_AUX16MHZ_1_DIV_SHIFT); 930 break; 931 default: 932 return -ENOENT; 933 } 934 935 return rk3588_aux16m_get_clk(priv, clk_id); 936 } 937 938 static ulong rk3588_aclk_vop_get_clk(struct rk3588_clk_priv *priv, ulong clk_id) 939 { 940 struct rk3588_cru *cru = priv->cru; 941 u32 div, sel, con, parent; 942 943 switch (clk_id) { 944 case ACLK_VOP_ROOT: 945 case ACLK_VOP: 946 con = readl(&cru->clksel_con[110]); 947 div = (con & ACLK_VOP_ROOT_DIV_MASK) >> ACLK_VOP_ROOT_DIV_SHIFT; 948 sel = (con & ACLK_VOP_ROOT_SEL_MASK) >> ACLK_VOP_ROOT_SEL_SHIFT; 949 if (sel == ACLK_VOP_ROOT_SEL_GPLL) 950 parent = priv->gpll_hz; 951 else if (sel == ACLK_VOP_ROOT_SEL_CPLL) 952 parent = priv->cpll_hz; 953 else if (sel == ACLK_VOP_ROOT_SEL_AUPLL) 954 parent = priv->aupll_hz; 955 else if (sel == ACLK_VOP_ROOT_SEL_NPLL) 956 parent = priv->npll_hz; 957 else 958 parent = 702 * MHz; 959 return DIV_TO_RATE(parent, div); 960 case ACLK_VOP_LOW_ROOT: 961 con = readl(&cru->clksel_con[110]); 962 sel = (con & ACLK_VOP_LOW_ROOT_SEL_MASK) >> 963 ACLK_VOP_LOW_ROOT_SEL_SHIFT; 964 if (sel == ACLK_VOP_LOW_ROOT_SEL_400M) 965 return 396 * MHz; 966 else if (sel == ACLK_VOP_LOW_ROOT_SEL_200M) 967 return 200 * MHz; 968 else if (sel == ACLK_VOP_LOW_ROOT_SEL_100M) 969 return 100 * MHz; 970 else 971 return OSC_HZ; 972 case HCLK_VOP_ROOT: 973 con = readl(&cru->clksel_con[110]); 974 sel = (con & HCLK_VOP_ROOT_SEL_MASK) >> HCLK_VOP_ROOT_SEL_SHIFT; 975 if (sel == HCLK_VOP_ROOT_SEL_200M) 976 return 200 * MHz; 977 else if (sel == HCLK_VOP_ROOT_SEL_100M) 978 return 100 * MHz; 979 else if (sel == HCLK_VOP_ROOT_SEL_50M) 980 return 50 * MHz; 981 else 982 return OSC_HZ; 983 default: 984 return -ENOENT; 985 } 986 } 987 988 static ulong rk3588_aclk_vop_set_clk(struct rk3588_clk_priv *priv, 989 ulong clk_id, ulong rate) 990 { 991 struct rk3588_cru *cru = priv->cru; 992 int src_clk, div; 993 994 switch (clk_id) { 995 case ACLK_VOP_ROOT: 996 case ACLK_VOP: 997 if (rate >= 850 * MHz) { 998 src_clk = ACLK_VOP_ROOT_SEL_NPLL; 999 div = 1; 1000 } else if (rate >= 750 * MHz) { 1001 src_clk = ACLK_VOP_ROOT_SEL_CPLL; 1002 div = 2; 1003 } else if (rate >= 700 * MHz) { 1004 src_clk = ACLK_VOP_ROOT_SEL_SPLL; 1005 div = 1; 1006 } else if (!(priv->cpll_hz % rate)) { 1007 src_clk = ACLK_VOP_ROOT_SEL_CPLL; 1008 div = DIV_ROUND_UP(priv->cpll_hz, rate); 1009 } else { 1010 src_clk = ACLK_VOP_ROOT_SEL_GPLL; 1011 div = DIV_ROUND_UP(priv->gpll_hz, rate); 1012 } 1013 rk_clrsetreg(&cru->clksel_con[110], 1014 ACLK_VOP_ROOT_DIV_MASK | 1015 ACLK_VOP_ROOT_SEL_MASK, 1016 (src_clk << ACLK_VOP_ROOT_SEL_SHIFT) | 1017 (div - 1) << ACLK_VOP_ROOT_DIV_SHIFT); 1018 break; 1019 case ACLK_VOP_LOW_ROOT: 1020 if (rate == 400 * MHz || rate == 396 * MHz) 1021 src_clk = ACLK_VOP_LOW_ROOT_SEL_400M; 1022 else if (rate == 200 * MHz) 1023 src_clk = ACLK_VOP_LOW_ROOT_SEL_200M; 1024 else if (rate == 100 * MHz) 1025 src_clk = ACLK_VOP_LOW_ROOT_SEL_100M; 1026 else 1027 src_clk = ACLK_VOP_LOW_ROOT_SEL_24M; 1028 rk_clrsetreg(&cru->clksel_con[110], 1029 ACLK_VOP_LOW_ROOT_SEL_MASK, 1030 src_clk << ACLK_VOP_LOW_ROOT_SEL_SHIFT); 1031 break; 1032 case HCLK_VOP_ROOT: 1033 if (rate == 200 * MHz) 1034 src_clk = HCLK_VOP_ROOT_SEL_200M; 1035 else if (rate == 100 * MHz) 1036 src_clk = HCLK_VOP_ROOT_SEL_100M; 1037 else if (rate == 50 * MHz) 1038 src_clk = HCLK_VOP_ROOT_SEL_50M; 1039 else 1040 src_clk = HCLK_VOP_ROOT_SEL_24M; 1041 rk_clrsetreg(&cru->clksel_con[110], 1042 HCLK_VOP_ROOT_SEL_MASK, 1043 src_clk << HCLK_VOP_ROOT_SEL_SHIFT); 1044 break; 1045 default: 1046 return -ENOENT; 1047 } 1048 1049 return rk3588_aclk_vop_get_clk(priv, clk_id); 1050 } 1051 1052 static ulong rk3588_dclk_vop_get_clk(struct rk3588_clk_priv *priv, ulong clk_id) 1053 { 1054 struct rk3588_cru *cru = priv->cru; 1055 u32 div, sel, con, parent; 1056 1057 switch (clk_id) { 1058 case DCLK_VOP0: 1059 case DCLK_VOP0_SRC: 1060 con = readl(&cru->clksel_con[111]); 1061 div = (con & DCLK0_VOP_SRC_DIV_MASK) >> DCLK0_VOP_SRC_DIV_SHIFT; 1062 sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT; 1063 break; 1064 case DCLK_VOP1: 1065 case DCLK_VOP1_SRC: 1066 con = readl(&cru->clksel_con[111]); 1067 div = (con & DCLK1_VOP_SRC_DIV_MASK) >> DCLK1_VOP_SRC_DIV_SHIFT; 1068 sel = (con & DCLK1_VOP_SRC_SEL_MASK) >> DCLK1_VOP_SRC_SEL_SHIFT; 1069 break; 1070 case DCLK_VOP2: 1071 case DCLK_VOP2_SRC: 1072 con = readl(&cru->clksel_con[112]); 1073 div = (con & DCLK2_VOP_SRC_DIV_MASK) >> DCLK2_VOP_SRC_DIV_SHIFT; 1074 sel = (con & DCLK2_VOP_SRC_SEL_MASK) >> DCLK2_VOP_SRC_SEL_SHIFT; 1075 break; 1076 case DCLK_VOP3: 1077 con = readl(&cru->clksel_con[113]); 1078 div = (con & DCLK3_VOP_SRC_DIV_MASK) >> DCLK3_VOP_SRC_DIV_SHIFT; 1079 sel = (con & DCLK3_VOP_SRC_SEL_MASK) >> DCLK3_VOP_SRC_SEL_SHIFT; 1080 break; 1081 default: 1082 return -ENOENT; 1083 } 1084 1085 if (sel == DCLK_VOP_SRC_SEL_AUPLL) 1086 parent = priv->aupll_hz; 1087 else if (sel == DCLK_VOP_SRC_SEL_V0PLL) 1088 parent = rockchip_pll_get_rate(&rk3588_pll_clks[V0PLL], 1089 priv->cru, V0PLL); 1090 else if (sel == DCLK_VOP_SRC_SEL_GPLL) 1091 parent = priv->gpll_hz; 1092 else if (sel == DCLK_VOP_SRC_SEL_CPLL) 1093 parent = priv->cpll_hz; 1094 else 1095 return -ENOENT; 1096 1097 return DIV_TO_RATE(parent, div); 1098 } 1099 1100 #define RK3588_VOP_PLL_LIMIT_FREQ 600000000 1101 1102 static ulong rk3588_dclk_vop_set_clk(struct rk3588_clk_priv *priv, 1103 ulong clk_id, ulong rate) 1104 { 1105 struct rk3588_cru *cru = priv->cru; 1106 ulong pll_rate, now, best_rate = 0; 1107 u32 i, conid, con, sel, div, best_div = 0, best_sel = 0; 1108 u32 mask, div_shift, sel_shift; 1109 1110 switch (clk_id) { 1111 case DCLK_VOP0: 1112 case DCLK_VOP0_SRC: 1113 conid = 111; 1114 con = readl(&cru->clksel_con[111]); 1115 sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT; 1116 mask = DCLK0_VOP_SRC_SEL_MASK | DCLK0_VOP_SRC_DIV_MASK; 1117 div_shift = DCLK0_VOP_SRC_DIV_SHIFT; 1118 sel_shift = DCLK0_VOP_SRC_SEL_SHIFT; 1119 break; 1120 case DCLK_VOP1: 1121 case DCLK_VOP1_SRC: 1122 conid = 111; 1123 con = readl(&cru->clksel_con[111]); 1124 sel = (con & DCLK1_VOP_SRC_SEL_MASK) >> DCLK1_VOP_SRC_SEL_SHIFT; 1125 mask = DCLK1_VOP_SRC_SEL_MASK | DCLK1_VOP_SRC_DIV_MASK; 1126 div_shift = DCLK1_VOP_SRC_DIV_SHIFT; 1127 sel_shift = DCLK1_VOP_SRC_SEL_SHIFT; 1128 break; 1129 case DCLK_VOP2: 1130 case DCLK_VOP2_SRC: 1131 conid = 112; 1132 con = readl(&cru->clksel_con[112]); 1133 sel = (con & DCLK2_VOP_SRC_SEL_MASK) >> DCLK2_VOP_SRC_SEL_SHIFT; 1134 mask = DCLK2_VOP_SRC_SEL_MASK | DCLK2_VOP_SRC_DIV_MASK; 1135 div_shift = DCLK2_VOP_SRC_DIV_SHIFT; 1136 sel_shift = DCLK2_VOP_SRC_SEL_SHIFT; 1137 break; 1138 case DCLK_VOP3: 1139 conid = 113; 1140 con = readl(&cru->clksel_con[113]); 1141 sel = (con & DCLK3_VOP_SRC_SEL_MASK) >> DCLK3_VOP_SRC_SEL_SHIFT; 1142 mask = DCLK3_VOP_SRC_SEL_MASK | DCLK3_VOP_SRC_DIV_MASK; 1143 div_shift = DCLK3_VOP_SRC_DIV_SHIFT; 1144 sel_shift = DCLK3_VOP_SRC_SEL_SHIFT; 1145 break; 1146 default: 1147 return -ENOENT; 1148 } 1149 1150 if (sel == DCLK_VOP_SRC_SEL_V0PLL) { 1151 div = DIV_ROUND_UP(RK3588_VOP_PLL_LIMIT_FREQ, rate); 1152 rk_clrsetreg(&cru->clksel_con[conid], 1153 mask, 1154 DCLK_VOP_SRC_SEL_V0PLL << sel_shift | 1155 ((div - 1) << div_shift)); 1156 rockchip_pll_set_rate(&rk3588_pll_clks[V0PLL], 1157 priv->cru, V0PLL, div * rate); 1158 } else { 1159 for (i = 0; i <= DCLK_VOP_SRC_SEL_AUPLL; i++) { 1160 switch (i) { 1161 case DCLK_VOP_SRC_SEL_GPLL: 1162 pll_rate = priv->gpll_hz; 1163 break; 1164 case DCLK_VOP_SRC_SEL_CPLL: 1165 pll_rate = priv->cpll_hz; 1166 break; 1167 case DCLK_VOP_SRC_SEL_AUPLL: 1168 pll_rate = priv->aupll_hz; 1169 break; 1170 case DCLK_VOP_SRC_SEL_V0PLL: 1171 pll_rate = 0; 1172 break; 1173 default: 1174 printf("do not support this vop pll sel\n"); 1175 return -EINVAL; 1176 } 1177 1178 div = DIV_ROUND_UP(pll_rate, rate); 1179 if (div > 255) 1180 continue; 1181 now = pll_rate / div; 1182 if (abs(rate - now) < abs(rate - best_rate)) { 1183 best_rate = now; 1184 best_div = div; 1185 best_sel = i; 1186 } 1187 debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n", 1188 pll_rate, best_rate, best_div, best_sel); 1189 } 1190 1191 if (best_rate) { 1192 rk_clrsetreg(&cru->clksel_con[conid], 1193 mask, 1194 best_sel << sel_shift | 1195 (best_div - 1) << div_shift); 1196 } else { 1197 printf("do not support this vop freq %lu\n", rate); 1198 return -EINVAL; 1199 } 1200 } 1201 return rk3588_dclk_vop_get_clk(priv, clk_id); 1202 } 1203 1204 static ulong rk3588_gmac_get_clk(struct rk3588_clk_priv *priv, ulong clk_id) 1205 { 1206 struct rk3588_cru *cru = priv->cru; 1207 u32 con, div; 1208 1209 switch (clk_id) { 1210 case CLK_GMAC0_PTP_REF: 1211 con = readl(&cru->clksel_con[81]); 1212 div = (con & CLK_GMAC0_PTP_DIV_MASK) >> CLK_GMAC0_PTP_DIV_SHIFT; 1213 return DIV_TO_RATE(priv->cpll_hz, div); 1214 case CLK_GMAC1_PTP_REF: 1215 con = readl(&cru->clksel_con[81]); 1216 div = (con & CLK_GMAC1_PTP_DIV_MASK) >> CLK_GMAC1_PTP_DIV_SHIFT; 1217 return DIV_TO_RATE(priv->cpll_hz, div); 1218 case CLK_GMAC_125M: 1219 con = readl(&cru->clksel_con[83]); 1220 div = (con & CLK_GMAC_125M_DIV_MASK) >> CLK_GMAC_125M_DIV_SHIFT; 1221 return DIV_TO_RATE(priv->cpll_hz, div); 1222 case CLK_GMAC_50M: 1223 con = readl(&cru->clksel_con[84]); 1224 div = (con & CLK_GMAC_50M_DIV_MASK) >> CLK_GMAC_50M_DIV_SHIFT; 1225 return DIV_TO_RATE(priv->cpll_hz, div); 1226 default: 1227 return -ENOENT; 1228 } 1229 } 1230 1231 static ulong rk3588_gmac_set_clk(struct rk3588_clk_priv *priv, 1232 ulong clk_id, ulong rate) 1233 { 1234 struct rk3588_cru *cru = priv->cru; 1235 int div; 1236 1237 div = DIV_ROUND_UP(priv->cpll_hz, rate); 1238 1239 switch (clk_id) { 1240 case CLK_GMAC0_PTP_REF: 1241 rk_clrsetreg(&cru->clksel_con[81], 1242 CLK_GMAC0_PTP_DIV_MASK | CLK_GMAC0_PTP_SEL_MASK, 1243 CLK_GMAC0_PTP_SEL_CPLL << CLK_GMAC0_PTP_SEL_SHIFT | 1244 (div - 1) << CLK_GMAC0_PTP_DIV_SHIFT); 1245 break; 1246 case CLK_GMAC1_PTP_REF: 1247 rk_clrsetreg(&cru->clksel_con[81], 1248 CLK_GMAC1_PTP_DIV_MASK | CLK_GMAC1_PTP_SEL_MASK, 1249 CLK_GMAC1_PTP_SEL_CPLL << CLK_GMAC1_PTP_SEL_SHIFT | 1250 (div - 1) << CLK_GMAC1_PTP_DIV_SHIFT); 1251 break; 1252 1253 case CLK_GMAC_125M: 1254 rk_clrsetreg(&cru->clksel_con[83], 1255 CLK_GMAC_125M_DIV_MASK | CLK_GMAC_125M_SEL_MASK, 1256 CLK_GMAC_125M_SEL_CPLL << CLK_GMAC_125M_SEL_SHIFT | 1257 (div - 1) << CLK_GMAC_125M_DIV_SHIFT); 1258 break; 1259 case CLK_GMAC_50M: 1260 rk_clrsetreg(&cru->clksel_con[84], 1261 CLK_GMAC_50M_DIV_MASK | CLK_GMAC_50M_SEL_MASK, 1262 CLK_GMAC_50M_SEL_CPLL << CLK_GMAC_50M_SEL_SHIFT | 1263 (div - 1) << CLK_GMAC_50M_DIV_SHIFT); 1264 break; 1265 default: 1266 return -ENOENT; 1267 } 1268 1269 return rk3588_gmac_get_clk(priv, clk_id); 1270 } 1271 1272 static ulong rk3588_uart_get_rate(struct rk3588_clk_priv *priv, ulong clk_id) 1273 { 1274 struct rk3588_cru *cru = priv->cru; 1275 u32 reg, con, fracdiv, div, src, p_src, p_rate; 1276 unsigned long m, n; 1277 1278 switch (clk_id) { 1279 case SCLK_UART1: 1280 reg = 41; 1281 break; 1282 case SCLK_UART2: 1283 reg = 43; 1284 break; 1285 case SCLK_UART3: 1286 reg = 45; 1287 break; 1288 case SCLK_UART4: 1289 reg = 47; 1290 break; 1291 case SCLK_UART5: 1292 reg = 49; 1293 break; 1294 case SCLK_UART6: 1295 reg = 51; 1296 break; 1297 case SCLK_UART7: 1298 reg = 53; 1299 break; 1300 case SCLK_UART8: 1301 reg = 55; 1302 break; 1303 case SCLK_UART9: 1304 reg = 57; 1305 break; 1306 default: 1307 return -ENOENT; 1308 } 1309 con = readl(&cru->clksel_con[reg + 2]); 1310 src = (con & CLK_UART_SEL_MASK) >> CLK_UART_SEL_SHIFT; 1311 con = readl(&cru->clksel_con[reg]); 1312 div = (con & CLK_UART_SRC_DIV_MASK) >> CLK_UART_SRC_DIV_SHIFT; 1313 p_src = (con & CLK_UART_SRC_SEL_MASK) >> CLK_UART_SRC_SEL_SHIFT; 1314 if (p_src == CLK_UART_SRC_SEL_GPLL) 1315 p_rate = priv->gpll_hz; 1316 else 1317 p_rate = priv->cpll_hz; 1318 1319 if (src == CLK_UART_SEL_SRC) { 1320 return DIV_TO_RATE(p_rate, div); 1321 } else if (src == CLK_UART_SEL_FRAC) { 1322 fracdiv = readl(&cru->clksel_con[reg + 1]); 1323 n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK; 1324 n >>= CLK_UART_FRAC_NUMERATOR_SHIFT; 1325 m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK; 1326 m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT; 1327 return DIV_TO_RATE(p_rate, div) * n / m; 1328 } else { 1329 return OSC_HZ; 1330 } 1331 } 1332 1333 static ulong rk3588_uart_set_rate(struct rk3588_clk_priv *priv, 1334 ulong clk_id, ulong rate) 1335 { 1336 struct rk3588_cru *cru = priv->cru; 1337 u32 reg, clk_src, uart_src, div; 1338 unsigned long m = 0, n = 0, val; 1339 1340 if (priv->gpll_hz % rate == 0) { 1341 clk_src = CLK_UART_SRC_SEL_GPLL; 1342 uart_src = CLK_UART_SEL_SRC; 1343 div = DIV_ROUND_UP(priv->gpll_hz, rate); 1344 } else if (priv->cpll_hz % rate == 0) { 1345 clk_src = CLK_UART_SRC_SEL_CPLL; 1346 uart_src = CLK_UART_SEL_SRC; 1347 div = DIV_ROUND_UP(priv->gpll_hz, rate); 1348 } else if (rate == OSC_HZ) { 1349 clk_src = CLK_UART_SRC_SEL_GPLL; 1350 uart_src = CLK_UART_SEL_XIN24M; 1351 div = 2; 1352 } else { 1353 clk_src = CLK_UART_SRC_SEL_GPLL; 1354 uart_src = CLK_UART_SEL_FRAC; 1355 div = 2; 1356 rational_best_approximation(rate, priv->gpll_hz / div, 1357 GENMASK(16 - 1, 0), 1358 GENMASK(16 - 1, 0), 1359 &m, &n); 1360 } 1361 1362 switch (clk_id) { 1363 case SCLK_UART1: 1364 reg = 41; 1365 break; 1366 case SCLK_UART2: 1367 reg = 43; 1368 break; 1369 case SCLK_UART3: 1370 reg = 45; 1371 break; 1372 case SCLK_UART4: 1373 reg = 47; 1374 break; 1375 case SCLK_UART5: 1376 reg = 49; 1377 break; 1378 case SCLK_UART6: 1379 reg = 51; 1380 break; 1381 case SCLK_UART7: 1382 reg = 53; 1383 break; 1384 case SCLK_UART8: 1385 reg = 55; 1386 break; 1387 case SCLK_UART9: 1388 reg = 57; 1389 break; 1390 default: 1391 return -ENOENT; 1392 } 1393 rk_clrsetreg(&cru->clksel_con[reg], 1394 CLK_UART_SRC_SEL_MASK | 1395 CLK_UART_SRC_DIV_MASK, 1396 (clk_src << CLK_UART_SRC_SEL_SHIFT) | 1397 ((div - 1) << CLK_UART_SRC_DIV_SHIFT)); 1398 rk_clrsetreg(&cru->clksel_con[reg + 2], 1399 CLK_UART_SEL_MASK, 1400 (uart_src << CLK_UART_SEL_SHIFT)); 1401 if (m && n) { 1402 val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n; 1403 writel(val, &cru->clksel_con[reg + 1]); 1404 } 1405 1406 return rk3588_uart_get_rate(priv, clk_id); 1407 } 1408 1409 static ulong rk3588_pciephy_get_rate(struct rk3588_clk_priv *priv, ulong clk_id) 1410 { 1411 struct rk3588_cru *cru = priv->cru; 1412 u32 con, div, src; 1413 1414 switch (clk_id) { 1415 case CLK_REF_PIPE_PHY0: 1416 con = readl(&cru->clksel_con[177]); 1417 src = (con & CLK_PCIE_PHY0_REF_SEL_MASK) >> CLK_PCIE_PHY0_REF_SEL_SHIFT; 1418 con = readl(&cru->clksel_con[176]); 1419 div = (con & CLK_PCIE_PHY0_PLL_DIV_MASK) >> CLK_PCIE_PHY0_PLL_DIV_SHIFT; 1420 break; 1421 case CLK_REF_PIPE_PHY1: 1422 con = readl(&cru->clksel_con[177]); 1423 src = (con & CLK_PCIE_PHY1_REF_SEL_MASK) >> CLK_PCIE_PHY1_REF_SEL_SHIFT; 1424 con = readl(&cru->clksel_con[176]); 1425 div = (con & CLK_PCIE_PHY1_PLL_DIV_MASK) >> CLK_PCIE_PHY1_PLL_DIV_SHIFT; 1426 break; 1427 case CLK_REF_PIPE_PHY2: 1428 con = readl(&cru->clksel_con[177]); 1429 src = (con & CLK_PCIE_PHY2_REF_SEL_MASK) >> CLK_PCIE_PHY2_REF_SEL_SHIFT; 1430 div = (con & CLK_PCIE_PHY2_PLL_DIV_MASK) >> CLK_PCIE_PHY2_PLL_DIV_SHIFT; 1431 break; 1432 default: 1433 return -ENOENT; 1434 } 1435 1436 if (src == CLK_PCIE_PHY_REF_SEL_PPLL) { 1437 return DIV_TO_RATE(priv->ppll_hz, div); 1438 } else { 1439 return OSC_HZ; 1440 } 1441 } 1442 1443 static ulong rk3588_pciephy_set_rate(struct rk3588_clk_priv *priv, 1444 ulong clk_id, ulong rate) 1445 { 1446 struct rk3588_cru *cru = priv->cru; 1447 u32 clk_src, div; 1448 1449 if (rate == OSC_HZ) { 1450 clk_src = CLK_PCIE_PHY_REF_SEL_24M; 1451 div = 1; 1452 } else { 1453 clk_src = CLK_PCIE_PHY_REF_SEL_PPLL; 1454 div = DIV_ROUND_UP(priv->ppll_hz, rate); 1455 } 1456 1457 switch (clk_id) { 1458 case CLK_REF_PIPE_PHY0: 1459 rk_clrsetreg(&cru->clksel_con[177], 1460 CLK_PCIE_PHY0_REF_SEL_MASK, 1461 (clk_src << CLK_PCIE_PHY0_REF_SEL_SHIFT)); 1462 rk_clrsetreg(&cru->clksel_con[176], 1463 CLK_PCIE_PHY0_PLL_DIV_MASK, 1464 ((div - 1) << CLK_PCIE_PHY0_PLL_DIV_SHIFT)); 1465 break; 1466 case CLK_REF_PIPE_PHY1: 1467 rk_clrsetreg(&cru->clksel_con[177], 1468 CLK_PCIE_PHY1_REF_SEL_MASK, 1469 (clk_src << CLK_PCIE_PHY1_REF_SEL_SHIFT)); 1470 rk_clrsetreg(&cru->clksel_con[176], 1471 CLK_PCIE_PHY1_PLL_DIV_MASK, 1472 ((div - 1) << CLK_PCIE_PHY1_PLL_DIV_SHIFT)); 1473 break; 1474 case CLK_REF_PIPE_PHY2: 1475 rk_clrsetreg(&cru->clksel_con[177], 1476 CLK_PCIE_PHY2_REF_SEL_MASK | 1477 CLK_PCIE_PHY2_PLL_DIV_MASK, 1478 (clk_src << CLK_PCIE_PHY2_REF_SEL_SHIFT) | 1479 ((div - 1) << CLK_PCIE_PHY2_PLL_DIV_SHIFT)); 1480 break; 1481 default: 1482 return -ENOENT; 1483 } 1484 1485 return rk3588_pciephy_get_rate(priv, clk_id); 1486 } 1487 #endif 1488 1489 static ulong rk3588_clk_get_rate(struct clk *clk) 1490 { 1491 struct rk3588_clk_priv *priv = dev_get_priv(clk->dev); 1492 ulong rate = 0; 1493 1494 if (!priv->gpll_hz) { 1495 printf("%s gpll=%lu\n", __func__, priv->gpll_hz); 1496 return -ENOENT; 1497 } 1498 1499 if (!priv->ppll_hz) { 1500 priv->ppll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL], 1501 priv->cru, PPLL); 1502 } 1503 1504 switch (clk->id) { 1505 case PLL_LPLL: 1506 rate = rockchip_pll_get_rate(&rk3588_pll_clks[LPLL], priv->cru, 1507 LPLL); 1508 break; 1509 case PLL_B0PLL: 1510 rate = rockchip_pll_get_rate(&rk3588_pll_clks[B0PLL], priv->cru, 1511 B0PLL); 1512 break; 1513 case PLL_B1PLL: 1514 rate = rockchip_pll_get_rate(&rk3588_pll_clks[B1PLL], priv->cru, 1515 B1PLL); 1516 break; 1517 case PLL_GPLL: 1518 rate = rockchip_pll_get_rate(&rk3588_pll_clks[GPLL], priv->cru, 1519 GPLL); 1520 break; 1521 case PLL_CPLL: 1522 rate = rockchip_pll_get_rate(&rk3588_pll_clks[CPLL], priv->cru, 1523 CPLL); 1524 break; 1525 case PLL_NPLL: 1526 rate = rockchip_pll_get_rate(&rk3588_pll_clks[NPLL], priv->cru, 1527 NPLL); 1528 break; 1529 case PLL_V0PLL: 1530 rate = rockchip_pll_get_rate(&rk3588_pll_clks[V0PLL], priv->cru, 1531 V0PLL); 1532 break; 1533 case PLL_AUPLL: 1534 rate = rockchip_pll_get_rate(&rk3588_pll_clks[AUPLL], priv->cru, 1535 AUPLL); 1536 break; 1537 case PLL_PPLL: 1538 rate = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL], priv->cru, 1539 PPLL); 1540 break; 1541 case ACLK_CENTER_ROOT: 1542 case PCLK_CENTER_ROOT: 1543 case HCLK_CENTER_ROOT: 1544 case ACLK_CENTER_LOW_ROOT: 1545 rate = rk3588_center_get_clk(priv, clk->id); 1546 break; 1547 case ACLK_TOP_ROOT: 1548 case PCLK_TOP_ROOT: 1549 case ACLK_LOW_TOP_ROOT: 1550 rate = rk3588_top_get_clk(priv, clk->id); 1551 break; 1552 case CLK_I2C0: 1553 case CLK_I2C1: 1554 case CLK_I2C2: 1555 case CLK_I2C3: 1556 case CLK_I2C4: 1557 case CLK_I2C5: 1558 case CLK_I2C6: 1559 case CLK_I2C7: 1560 case CLK_I2C8: 1561 rate = rk3588_i2c_get_clk(priv, clk->id); 1562 break; 1563 case CLK_SPI0: 1564 case CLK_SPI1: 1565 case CLK_SPI2: 1566 case CLK_SPI3: 1567 case CLK_SPI4: 1568 rate = rk3588_spi_get_clk(priv, clk->id); 1569 break; 1570 case CLK_PWM1: 1571 case CLK_PWM2: 1572 case CLK_PWM3: 1573 case CLK_PMU1PWM: 1574 rate = rk3588_pwm_get_clk(priv, clk->id); 1575 break; 1576 case CLK_SARADC: 1577 case CLK_TSADC: 1578 rate = rk3588_adc_get_clk(priv, clk->id); 1579 break; 1580 case CCLK_SRC_SDIO: 1581 case CCLK_EMMC: 1582 case BCLK_EMMC: 1583 case SCLK_SFC: 1584 case DCLK_DECOM: 1585 rate = rk3588_mmc_get_clk(priv, clk->id); 1586 break; 1587 #ifndef CONFIG_SPL_BUILD 1588 case CLK_AUX16M_0: 1589 case CLK_AUX16M_1: 1590 rk3588_aux16m_get_clk(priv, clk->id); 1591 break; 1592 case ACLK_VOP_ROOT: 1593 case ACLK_VOP: 1594 case ACLK_VOP_LOW_ROOT: 1595 case HCLK_VOP_ROOT: 1596 rate = rk3588_aclk_vop_get_clk(priv, clk->id); 1597 break; 1598 case DCLK_VOP0: 1599 case DCLK_VOP0_SRC: 1600 case DCLK_VOP1: 1601 case DCLK_VOP1_SRC: 1602 case DCLK_VOP2: 1603 case DCLK_VOP2_SRC: 1604 case DCLK_VOP3: 1605 rate = rk3588_dclk_vop_get_clk(priv, clk->id); 1606 break; 1607 case CLK_GMAC0_PTP_REF: 1608 case CLK_GMAC1_PTP_REF: 1609 case CLK_GMAC_125M: 1610 case CLK_GMAC_50M: 1611 rate = rk3588_gmac_get_clk(priv, clk->id); 1612 break; 1613 case SCLK_UART1: 1614 case SCLK_UART2: 1615 case SCLK_UART3: 1616 case SCLK_UART4: 1617 case SCLK_UART5: 1618 case SCLK_UART6: 1619 case SCLK_UART7: 1620 case SCLK_UART8: 1621 case SCLK_UART9: 1622 rate = rk3588_uart_get_rate(priv, clk->id); 1623 break; 1624 case CLK_REF_PIPE_PHY0: 1625 case CLK_REF_PIPE_PHY1: 1626 case CLK_REF_PIPE_PHY2: 1627 rate = rk3588_pciephy_get_rate(priv, clk->id); 1628 break; 1629 #endif 1630 default: 1631 return -ENOENT; 1632 } 1633 1634 return rate; 1635 }; 1636 1637 static ulong rk3588_clk_set_rate(struct clk *clk, ulong rate) 1638 { 1639 struct rk3588_clk_priv *priv = dev_get_priv(clk->dev); 1640 ulong ret = 0; 1641 1642 if (!priv->gpll_hz) { 1643 printf("%s gpll=%lu\n", __func__, priv->gpll_hz); 1644 return -ENOENT; 1645 } 1646 1647 if (!priv->ppll_hz) { 1648 priv->ppll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL], 1649 priv->cru, PPLL); 1650 } 1651 1652 switch (clk->id) { 1653 case PLL_CPLL: 1654 ret = rockchip_pll_set_rate(&rk3588_pll_clks[CPLL], priv->cru, 1655 CPLL, rate); 1656 priv->cpll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[CPLL], 1657 priv->cru, CPLL); 1658 break; 1659 case PLL_GPLL: 1660 ret = rockchip_pll_set_rate(&rk3588_pll_clks[GPLL], priv->cru, 1661 GPLL, rate); 1662 priv->gpll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[GPLL], 1663 priv->cru, GPLL); 1664 break; 1665 case PLL_NPLL: 1666 ret = rockchip_pll_set_rate(&rk3588_pll_clks[NPLL], priv->cru, 1667 NPLL, rate); 1668 break; 1669 case PLL_V0PLL: 1670 ret = rockchip_pll_set_rate(&rk3588_pll_clks[V0PLL], priv->cru, 1671 V0PLL, rate); 1672 priv->v0pll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[V0PLL], 1673 priv->cru, V0PLL); 1674 break; 1675 case PLL_AUPLL: 1676 ret = rockchip_pll_set_rate(&rk3588_pll_clks[AUPLL], priv->cru, 1677 AUPLL, rate); 1678 priv->aupll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[AUPLL], 1679 priv->cru, AUPLL); 1680 break; 1681 case PLL_PPLL: 1682 ret = rockchip_pll_set_rate(&rk3588_pll_clks[PPLL], priv->cru, 1683 PPLL, rate); 1684 priv->ppll_hz = rockchip_pll_get_rate(&rk3588_pll_clks[PPLL], 1685 priv->cru, PPLL); 1686 break; 1687 case ACLK_CENTER_ROOT: 1688 case PCLK_CENTER_ROOT: 1689 case HCLK_CENTER_ROOT: 1690 case ACLK_CENTER_LOW_ROOT: 1691 ret = rk3588_center_set_clk(priv, clk->id, rate); 1692 break; 1693 case ACLK_TOP_ROOT: 1694 case PCLK_TOP_ROOT: 1695 case ACLK_LOW_TOP_ROOT: 1696 ret = rk3588_top_set_clk(priv, clk->id, rate); 1697 break; 1698 case CLK_I2C0: 1699 case CLK_I2C1: 1700 case CLK_I2C2: 1701 case CLK_I2C3: 1702 case CLK_I2C4: 1703 case CLK_I2C5: 1704 case CLK_I2C6: 1705 case CLK_I2C7: 1706 case CLK_I2C8: 1707 ret = rk3588_i2c_set_clk(priv, clk->id, rate); 1708 break; 1709 case CLK_SPI0: 1710 case CLK_SPI1: 1711 case CLK_SPI2: 1712 case CLK_SPI3: 1713 case CLK_SPI4: 1714 ret = rk3588_spi_set_clk(priv, clk->id, rate); 1715 break; 1716 case CLK_PWM1: 1717 case CLK_PWM2: 1718 case CLK_PWM3: 1719 case CLK_PMU1PWM: 1720 ret = rk3588_pwm_set_clk(priv, clk->id, rate); 1721 break; 1722 case CLK_SARADC: 1723 case CLK_TSADC: 1724 ret = rk3588_adc_set_clk(priv, clk->id, rate); 1725 break; 1726 case CCLK_SRC_SDIO: 1727 case CCLK_EMMC: 1728 case BCLK_EMMC: 1729 case SCLK_SFC: 1730 case DCLK_DECOM: 1731 ret = rk3588_mmc_set_clk(priv, clk->id, rate); 1732 break; 1733 #ifndef CONFIG_SPL_BUILD 1734 case CLK_AUX16M_0: 1735 case CLK_AUX16M_1: 1736 rk3588_aux16m_set_clk(priv, clk->id, rate); 1737 break; 1738 case ACLK_VOP_ROOT: 1739 case ACLK_VOP: 1740 case ACLK_VOP_LOW_ROOT: 1741 case HCLK_VOP_ROOT: 1742 ret = rk3588_aclk_vop_set_clk(priv, clk->id, rate); 1743 break; 1744 case DCLK_VOP0: 1745 case DCLK_VOP0_SRC: 1746 case DCLK_VOP1: 1747 case DCLK_VOP1_SRC: 1748 case DCLK_VOP2: 1749 case DCLK_VOP2_SRC: 1750 case DCLK_VOP3: 1751 ret = rk3588_dclk_vop_set_clk(priv, clk->id, rate); 1752 break; 1753 case CLK_GMAC0_PTP_REF: 1754 case CLK_GMAC1_PTP_REF: 1755 case CLK_GMAC_125M: 1756 case CLK_GMAC_50M: 1757 ret = rk3588_gmac_set_clk(priv, clk->id, rate); 1758 break; 1759 case SCLK_UART1: 1760 case SCLK_UART2: 1761 case SCLK_UART3: 1762 case SCLK_UART4: 1763 case SCLK_UART5: 1764 case SCLK_UART6: 1765 case SCLK_UART7: 1766 case SCLK_UART8: 1767 case SCLK_UART9: 1768 ret = rk3588_uart_set_rate(priv, clk->id, rate); 1769 break; 1770 case CLK_REF_PIPE_PHY0: 1771 case CLK_REF_PIPE_PHY1: 1772 case CLK_REF_PIPE_PHY2: 1773 ret = rk3588_pciephy_set_rate(priv, clk->id, rate); 1774 break; 1775 #endif 1776 default: 1777 return -ENOENT; 1778 } 1779 1780 return ret; 1781 }; 1782 1783 #define ROCKCHIP_MMC_DELAY_SEL BIT(10) 1784 #define ROCKCHIP_MMC_DEGREE_MASK 0x3 1785 #define ROCKCHIP_MMC_DELAYNUM_OFFSET 2 1786 #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET) 1787 1788 #define PSECS_PER_SEC 1000000000000LL 1789 /* 1790 * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to 1791 * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg. 1792 */ 1793 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60 1794 1795 int rk3588_mmc_get_phase(struct clk *clk) 1796 { 1797 struct rk3588_clk_priv *priv = dev_get_priv(clk->dev); 1798 struct rk3588_cru *cru = priv->cru; 1799 u32 raw_value, delay_num; 1800 u16 degrees = 0; 1801 ulong rate; 1802 1803 rate = rk3588_clk_get_rate(clk); 1804 if (rate < 0) 1805 return rate; 1806 1807 if (clk->id == SCLK_SDMMC_SAMPLE) 1808 raw_value = readl(&cru->sdmmc_con[1]); 1809 else 1810 return 0; 1811 1812 raw_value >>= 1; 1813 degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90; 1814 1815 if (raw_value & ROCKCHIP_MMC_DELAY_SEL) { 1816 /* degrees/delaynum * 10000 */ 1817 unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) * 1818 36 * (rate / 1000000); 1819 1820 delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK); 1821 delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET; 1822 degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000); 1823 } 1824 1825 return degrees % 360; 1826 } 1827 1828 int rk3588_mmc_set_phase(struct clk *clk, u32 degrees) 1829 { 1830 struct rk3588_clk_priv *priv = dev_get_priv(clk->dev); 1831 struct rk3588_cru *cru = priv->cru; 1832 u8 nineties, remainder, delay_num; 1833 u32 raw_value, delay; 1834 ulong rate; 1835 1836 rate = rk3588_clk_get_rate(clk); 1837 if (rate < 0) 1838 return rate; 1839 1840 nineties = degrees / 90; 1841 remainder = (degrees % 90); 1842 1843 /* 1844 * Convert to delay; do a little extra work to make sure we 1845 * don't overflow 32-bit / 64-bit numbers. 1846 */ 1847 delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */ 1848 delay *= remainder; 1849 delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 * 1850 (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10)); 1851 1852 delay_num = (u8)min_t(u32, delay, 255); 1853 1854 raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0; 1855 raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET; 1856 raw_value |= nineties; 1857 1858 raw_value <<= 1; 1859 if (clk->id == SCLK_SDMMC_SAMPLE) 1860 writel(raw_value | 0xffff0000, &cru->sdmmc_con[1]); 1861 1862 debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n", 1863 degrees, delay_num, raw_value, rk3588_mmc_get_phase(clk)); 1864 1865 return 0; 1866 } 1867 1868 static int rk3588_clk_get_phase(struct clk *clk) 1869 { 1870 int ret; 1871 1872 debug("%s %ld\n", __func__, clk->id); 1873 switch (clk->id) { 1874 case SCLK_SDMMC_SAMPLE: 1875 ret = rk3588_mmc_get_phase(clk); 1876 break; 1877 default: 1878 return -ENOENT; 1879 } 1880 1881 return ret; 1882 } 1883 1884 static int rk3588_clk_set_phase(struct clk *clk, int degrees) 1885 { 1886 int ret; 1887 1888 debug("%s %ld\n", __func__, clk->id); 1889 switch (clk->id) { 1890 case SCLK_SDMMC_SAMPLE: 1891 ret = rk3588_mmc_set_phase(clk, degrees); 1892 break; 1893 default: 1894 return -ENOENT; 1895 } 1896 1897 return ret; 1898 } 1899 1900 #if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA)) 1901 static int __maybe_unused rk3588_dclk_vop_set_parent(struct clk *clk, 1902 struct clk *parent) 1903 { 1904 struct rk3588_clk_priv *priv = dev_get_priv(clk->dev); 1905 struct rk3588_cru *cru = priv->cru; 1906 u32 sel; 1907 const char *clock_dev_name = parent->dev->name; 1908 1909 if (parent->id == PLL_V0PLL) 1910 sel = 2; 1911 else if (parent->id == PLL_GPLL) 1912 sel = 0; 1913 else if (parent->id == PLL_CPLL) 1914 sel = 1; 1915 else 1916 sel = 3; 1917 1918 switch (clk->id) { 1919 case DCLK_VOP0_SRC: 1920 rk_clrsetreg(&cru->clksel_con[111], DCLK0_VOP_SRC_SEL_MASK, 1921 sel << DCLK0_VOP_SRC_SEL_SHIFT); 1922 break; 1923 case DCLK_VOP1_SRC: 1924 rk_clrsetreg(&cru->clksel_con[111], DCLK1_VOP_SRC_SEL_MASK, 1925 sel << DCLK1_VOP_SRC_SEL_SHIFT); 1926 break; 1927 case DCLK_VOP2_SRC: 1928 rk_clrsetreg(&cru->clksel_con[112], DCLK2_VOP_SRC_SEL_MASK, 1929 sel << DCLK2_VOP_SRC_SEL_SHIFT); 1930 break; 1931 case DCLK_VOP3: 1932 rk_clrsetreg(&cru->clksel_con[113], DCLK3_VOP_SRC_SEL_MASK, 1933 sel << DCLK3_VOP_SRC_SEL_SHIFT); 1934 break; 1935 case DCLK_VOP0: 1936 if (!strcmp(clock_dev_name, "hdmiphypll_clk0")) 1937 sel = 1; 1938 else if (!strcmp(clock_dev_name, "hdmiphypll_clk1")) 1939 sel = 2; 1940 else 1941 sel = 0; 1942 rk_clrsetreg(&cru->clksel_con[112], DCLK0_VOP_SEL_MASK, 1943 sel << DCLK0_VOP_SEL_SHIFT); 1944 break; 1945 case DCLK_VOP1: 1946 if (!strcmp(clock_dev_name, "hdmiphypll_clk0")) 1947 sel = 1; 1948 else if (!strcmp(clock_dev_name, "hdmiphypll_clk1")) 1949 sel = 2; 1950 else 1951 sel = 0; 1952 rk_clrsetreg(&cru->clksel_con[112], DCLK1_VOP_SEL_MASK, 1953 sel << DCLK1_VOP_SEL_SHIFT); 1954 break; 1955 case DCLK_VOP2: 1956 if (!strcmp(clock_dev_name, "hdmiphypll_clk0")) 1957 sel = 1; 1958 else if (!strcmp(clock_dev_name, "hdmiphypll_clk1")) 1959 sel = 2; 1960 else 1961 sel = 0; 1962 rk_clrsetreg(&cru->clksel_con[112], DCLK2_VOP_SEL_MASK, 1963 sel << DCLK2_VOP_SEL_SHIFT); 1964 break; 1965 default: 1966 return -EINVAL; 1967 } 1968 return 0; 1969 } 1970 1971 static int rk3588_clk_set_parent(struct clk *clk, struct clk *parent) 1972 { 1973 switch (clk->id) { 1974 case DCLK_VOP0_SRC: 1975 case DCLK_VOP1_SRC: 1976 case DCLK_VOP2_SRC: 1977 case DCLK_VOP0: 1978 case DCLK_VOP1: 1979 case DCLK_VOP2: 1980 case DCLK_VOP3: 1981 return rk3588_dclk_vop_set_parent(clk, parent); 1982 default: 1983 return -ENOENT; 1984 } 1985 1986 return 0; 1987 } 1988 #endif 1989 1990 static struct clk_ops rk3588_clk_ops = { 1991 .get_rate = rk3588_clk_get_rate, 1992 .set_rate = rk3588_clk_set_rate, 1993 .get_phase = rk3588_clk_get_phase, 1994 .set_phase = rk3588_clk_set_phase, 1995 #if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA)) 1996 .set_parent = rk3588_clk_set_parent, 1997 #endif 1998 }; 1999 2000 static void rk3588_clk_init(struct rk3588_clk_priv *priv) 2001 { 2002 int ret, div; 2003 2004 priv->sync_kernel = false; 2005 if (!priv->armclk_enter_hz) { 2006 ret = rockchip_pll_set_rate(&rk3588_pll_clks[LPLL], priv->cru, 2007 LPLL, LPLL_HZ); 2008 priv->armclk_enter_hz = 2009 rockchip_pll_get_rate(&rk3588_pll_clks[LPLL], 2010 priv->cru, LPLL); 2011 priv->armclk_init_hz = priv->armclk_enter_hz; 2012 } 2013 2014 div = DIV_ROUND_UP(GPLL_HZ, 300 * MHz); 2015 rk_clrsetreg(&priv->cru->clksel_con[38], 2016 ACLK_BUS_ROOT_SEL_MASK | 2017 ACLK_BUS_ROOT_DIV_MASK, 2018 div << ACLK_BUS_ROOT_DIV_SHIFT); 2019 2020 if (priv->cpll_hz != CPLL_HZ) { 2021 ret = rockchip_pll_set_rate(&rk3588_pll_clks[CPLL], priv->cru, 2022 CPLL, CPLL_HZ); 2023 if (!ret) 2024 priv->cpll_hz = CPLL_HZ; 2025 } 2026 if (priv->gpll_hz != GPLL_HZ) { 2027 ret = rockchip_pll_set_rate(&rk3588_pll_clks[GPLL], priv->cru, 2028 GPLL, GPLL_HZ); 2029 if (!ret) 2030 priv->gpll_hz = GPLL_HZ; 2031 } 2032 2033 rk_clrsetreg(&priv->cru->clksel_con[9], 2034 ACLK_TOP_S400_SEL_MASK | 2035 ACLK_TOP_S200_SEL_MASK, 2036 (ACLK_TOP_S400_SEL_400M << ACLK_TOP_S400_SEL_SHIFT) | 2037 (ACLK_TOP_S200_SEL_200M << ACLK_TOP_S200_SEL_SHIFT)); 2038 } 2039 2040 static int rk3588_clk_probe(struct udevice *dev) 2041 { 2042 struct rk3588_clk_priv *priv = dev_get_priv(dev); 2043 int ret; 2044 struct clk clk; 2045 2046 #ifdef CONFIG_SPL_BUILD 2047 rockchip_pll_set_rate(&rk3588_pll_clks[B0PLL], priv->cru, 2048 B0PLL, LPLL_HZ); 2049 rockchip_pll_set_rate(&rk3588_pll_clks[B1PLL], priv->cru, 2050 B1PLL, LPLL_HZ); 2051 #endif 2052 2053 ret = rockchip_get_scmi_clk(&clk.dev); 2054 if (ret) { 2055 printf("Failed to get scmi clk dev\n"); 2056 return ret; 2057 } 2058 clk.id = SCMI_SPLL; 2059 ret = clk_set_rate(&clk, 702000000); 2060 if (ret < 0) { 2061 printf("Failed to set spll\n"); 2062 } 2063 2064 clk.id = SCMI_CLK_CPUB01; 2065 ret = clk_set_rate(&clk, LPLL_HZ); 2066 if (ret < 0) 2067 printf("Failed to set cpub01\n"); 2068 clk.id = SCMI_CLK_CPUB23; 2069 ret = clk_set_rate(&clk, LPLL_HZ); 2070 if (ret < 0) 2071 printf("Failed to set cpub23\n"); 2072 2073 priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 2074 if (IS_ERR(priv->grf)) 2075 return PTR_ERR(priv->grf); 2076 2077 rk3588_clk_init(priv); 2078 2079 /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */ 2080 ret = clk_set_defaults(dev); 2081 if (ret) 2082 debug("%s clk_set_defaults failed %d\n", __func__, ret); 2083 else 2084 priv->sync_kernel = true; 2085 2086 return 0; 2087 } 2088 2089 static int rk3588_clk_ofdata_to_platdata(struct udevice *dev) 2090 { 2091 struct rk3588_clk_priv *priv = dev_get_priv(dev); 2092 2093 priv->cru = dev_read_addr_ptr(dev); 2094 2095 return 0; 2096 } 2097 2098 static int rk3588_clk_bind(struct udevice *dev) 2099 { 2100 int ret; 2101 struct udevice *sys_child, *sf_child; 2102 struct sysreset_reg *priv; 2103 struct softreset_reg *sf_priv; 2104 2105 /* The reset driver does not have a device node, so bind it here */ 2106 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset", 2107 &sys_child); 2108 if (ret) { 2109 debug("Warning: No sysreset driver: ret=%d\n", ret); 2110 } else { 2111 priv = malloc(sizeof(struct sysreset_reg)); 2112 priv->glb_srst_fst_value = offsetof(struct rk3588_cru, 2113 glb_srst_fst); 2114 priv->glb_srst_snd_value = offsetof(struct rk3588_cru, 2115 glb_srsr_snd); 2116 sys_child->priv = priv; 2117 } 2118 2119 ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset", 2120 dev_ofnode(dev), &sf_child); 2121 if (ret) { 2122 debug("Warning: No rockchip reset driver: ret=%d\n", ret); 2123 } else { 2124 sf_priv = malloc(sizeof(struct softreset_reg)); 2125 sf_priv->sf_reset_offset = offsetof(struct rk3588_cru, 2126 softrst_con[0]); 2127 sf_priv->sf_reset_num = 49158; 2128 sf_child->priv = sf_priv; 2129 } 2130 2131 return 0; 2132 } 2133 2134 static const struct udevice_id rk3588_clk_ids[] = { 2135 { .compatible = "rockchip,rk3588-cru" }, 2136 { } 2137 }; 2138 2139 U_BOOT_DRIVER(rockchip_rk3588_cru) = { 2140 .name = "rockchip_rk3588_cru", 2141 .id = UCLASS_CLK, 2142 .of_match = rk3588_clk_ids, 2143 .priv_auto_alloc_size = sizeof(struct rk3588_clk_priv), 2144 .ofdata_to_platdata = rk3588_clk_ofdata_to_platdata, 2145 .ops = &rk3588_clk_ops, 2146 .bind = rk3588_clk_bind, 2147 .probe = rk3588_clk_probe, 2148 }; 2149 2150 #ifdef CONFIG_SPL_BUILD 2151 #define SCRU_BASE 0xfd7d0000 2152 #define BUSSCRU_BASE 0xfd7d8000 2153 #define GPLL_RATE 1188000000 2154 #define SPLL_RATE 702000000 2155 2156 #ifndef BITS_WITH_WMASK 2157 #define BITS_WITH_WMASK(bits, msk, shift) \ 2158 ((bits) << (shift)) | ((msk) << ((shift) + 16)) 2159 #endif 2160 2161 #define CLKDIV_6BITS_SHF(div, shift) BITS_WITH_WMASK(div, 0x3fU, shift) 2162 #define CLKDIV_5BITS_SHF(div, shift) BITS_WITH_WMASK(div, 0x1fU, shift) 2163 2164 static ulong rk3588_clk_scmi_get_rate(struct clk *clk) 2165 { 2166 u32 src, div; 2167 2168 switch (clk->id) { 2169 case SCMI_SPLL: 2170 src = readl(BUSSCRU_BASE + RK3588_MODE_CON0) & 0x3; 2171 if (src == 0) 2172 return OSC_HZ; 2173 else if (src == 1) 2174 return 702 * MHz; 2175 else 2176 return 32768; 2177 case SCMI_CCLK_SD: 2178 src = readl(SCRU_BASE + RK3588_CLKSEL_CON(3)) & 0x3000; 2179 src = src >> 12; 2180 div = readl(SCRU_BASE + RK3588_CLKSEL_CON(3)) & 0x0fc0; 2181 div = div >> 6; 2182 if (src == 1) 2183 return SPLL_RATE / (div + 1); 2184 else if (src == 2) 2185 return OSC_HZ / (div + 1); 2186 else 2187 return GPLL_RATE / (div + 1); 2188 case SCMI_DCLK_SD: 2189 src = readl(SCRU_BASE + RK3588_CLKSEL_CON(3)) & 0x0020; 2190 div = readl(SCRU_BASE + RK3588_CLKSEL_CON(3)) & 0x001f; 2191 if (src) 2192 return SPLL_RATE / (div + 1); 2193 else 2194 return GPLL_RATE / (div + 1); 2195 case SCMI_CRYPTO_RNG: 2196 src = readl(SCRU_BASE + RK3588_CLKSEL_CON(1)) & 0xc000; 2197 src = src >> 14; 2198 if (src == 0) 2199 return 175 * MHz; 2200 else if (src == 1) 2201 return 116 * MHz; 2202 else if (src == 2) 2203 return 58 * MHz; 2204 else 2205 return OSC_HZ; 2206 case SCMI_CRYPTO_CORE: 2207 src = readl(SCRU_BASE + RK3588_CLKSEL_CON(1)) & 0x0c00; 2208 src = src >> 10; 2209 if (src == 0) 2210 return 350 * MHz; 2211 else if (src == 1) 2212 return 233 * MHz; 2213 else if (src == 2) 2214 return 116 * MHz; 2215 else 2216 return OSC_HZ; 2217 case SCMI_CRYPTO_PKA: 2218 src = readl(SCRU_BASE + RK3588_CLKSEL_CON(1)) & 0x3000; 2219 src = src >> 12; 2220 if (src == 0) 2221 return 350 * MHz; 2222 else if (src == 1) 2223 return 233 * MHz; 2224 else if (src == 2) 2225 return 116 * MHz; 2226 else 2227 return OSC_HZ; 2228 case SCMI_KEYLADDER_CORE: 2229 src = readl(SCRU_BASE + RK3588_CLKSEL_CON(2)) & 0x00c0; 2230 src = src >> 6; 2231 if (src == 0) 2232 return 350 * MHz; 2233 else if (src == 1) 2234 return 233 * MHz; 2235 else if (src == 2) 2236 return 116 * MHz; 2237 else 2238 return OSC_HZ; 2239 case SCMI_KEYLADDER_RNG: 2240 src = readl(SCRU_BASE + RK3588_CLKSEL_CON(2)) & 0x0300; 2241 src = src >> 8; 2242 if (src == 0) 2243 return 175 * MHz; 2244 else if (src == 1) 2245 return 116 * MHz; 2246 else if (src == 2) 2247 return 58 * MHz; 2248 else 2249 return OSC_HZ; 2250 case SCMI_TCLK_WDT: 2251 return OSC_HZ; 2252 case SCMI_HCLK_SD: 2253 case SCMI_HCLK_SECURE_NS: 2254 src = readl(SCRU_BASE + RK3588_CLKSEL_CON(1)) & 0x000c; 2255 src = src >> 2; 2256 if (src == 0) 2257 return 150 * MHz; 2258 else if (src == 1) 2259 return 100 * MHz; 2260 else if (src == 2) 2261 return 50 * MHz; 2262 else 2263 return OSC_HZ; 2264 default: 2265 return -ENOENT; 2266 } 2267 }; 2268 2269 static ulong rk3588_clk_scmi_set_rate(struct clk *clk, ulong rate) 2270 { 2271 u32 src, div; 2272 2273 if ((readl(BUSSCRU_BASE + RK3588_PLL_CON(137)) & 0x01c0) == 0xc0) { 2274 writel(BITS_WITH_WMASK(0, 0x3U, 0), 2275 BUSSCRU_BASE + RK3588_MODE_CON0); 2276 writel(BITS_WITH_WMASK(2, 0x7U, 6), 2277 BUSSCRU_BASE + RK3588_PLL_CON(137)); 2278 writel(BITS_WITH_WMASK(1, 0x3U, 0), 2279 BUSSCRU_BASE + RK3588_MODE_CON0); 2280 } 2281 2282 switch (clk->id) { 2283 case SCMI_SPLL: 2284 if (rate >= 700 * MHz) 2285 src = 1; 2286 else 2287 src = 0; 2288 writel(BITS_WITH_WMASK(0, 0x3U, 0), 2289 BUSSCRU_BASE + RK3588_MODE_CON0); 2290 writel(BITS_WITH_WMASK(2, 0x7U, 6), 2291 BUSSCRU_BASE + RK3588_PLL_CON(137)); 2292 writel(BITS_WITH_WMASK(src, 0x3U, 0), 2293 BUSSCRU_BASE + RK3588_MODE_CON0); 2294 break; 2295 case SCMI_CCLK_SD: 2296 if ((OSC_HZ % rate) == 0) { 2297 div = DIV_ROUND_UP(OSC_HZ, rate); 2298 writel(CLKDIV_6BITS_SHF(div - 1, 6) | 2299 BITS_WITH_WMASK(2U, 0x3U, 12), 2300 SCRU_BASE + RK3588_CLKSEL_CON(3)); 2301 } else if ((SPLL_RATE % rate) == 0) { 2302 div = DIV_ROUND_UP(SPLL_RATE, rate); 2303 writel(CLKDIV_6BITS_SHF(div - 1, 6) | 2304 BITS_WITH_WMASK(1U, 0x3U, 12), 2305 SCRU_BASE + RK3588_CLKSEL_CON(3)); 2306 } else { 2307 div = DIV_ROUND_UP(GPLL_RATE, rate); 2308 writel(CLKDIV_6BITS_SHF(div - 1, 6) | 2309 BITS_WITH_WMASK(0U, 0x3U, 12), 2310 SCRU_BASE + RK3588_CLKSEL_CON(3)); 2311 } 2312 break; 2313 case SCMI_DCLK_SD: 2314 if ((SPLL_RATE % rate) == 0) { 2315 div = DIV_ROUND_UP(SPLL_RATE, rate); 2316 writel(CLKDIV_5BITS_SHF(div - 1, 0) | 2317 BITS_WITH_WMASK(1U, 0x1U, 5), 2318 SCRU_BASE + RK3588_CLKSEL_CON(3)); 2319 } else { 2320 div = DIV_ROUND_UP(GPLL_RATE, rate); 2321 writel(CLKDIV_5BITS_SHF(div - 1, 0) | 2322 BITS_WITH_WMASK(0U, 0x1U, 5), 2323 SCRU_BASE + RK3588_CLKSEL_CON(3)); 2324 } 2325 break; 2326 case SCMI_CRYPTO_RNG: 2327 if (rate >= 175 * MHz) 2328 src = 0; 2329 else if (rate >= 116 * MHz) 2330 src = 1; 2331 else if (rate >= 58 * MHz) 2332 src = 2; 2333 else 2334 src = 3; 2335 2336 writel(BITS_WITH_WMASK(src, 0x3U, 14), 2337 SCRU_BASE + RK3588_CLKSEL_CON(1)); 2338 break; 2339 case SCMI_CRYPTO_CORE: 2340 if (rate >= 350 * MHz) 2341 src = 0; 2342 else if (rate >= 233 * MHz) 2343 src = 1; 2344 else if (rate >= 116 * MHz) 2345 src = 2; 2346 else 2347 src = 3; 2348 2349 writel(BITS_WITH_WMASK(src, 0x3U, 10), 2350 SCRU_BASE + RK3588_CLKSEL_CON(1)); 2351 break; 2352 case SCMI_CRYPTO_PKA: 2353 if (rate >= 350 * MHz) 2354 src = 0; 2355 else if (rate >= 233 * MHz) 2356 src = 1; 2357 else if (rate >= 116 * MHz) 2358 src = 2; 2359 else 2360 src = 3; 2361 2362 writel(BITS_WITH_WMASK(src, 0x3U, 12), 2363 SCRU_BASE + RK3588_CLKSEL_CON(1)); 2364 break; 2365 case SCMI_KEYLADDER_CORE: 2366 if (rate >= 350 * MHz) 2367 src = 0; 2368 else if (rate >= 233 * MHz) 2369 src = 1; 2370 else if (rate >= 116 * MHz) 2371 src = 2; 2372 else 2373 src = 3; 2374 2375 writel(BITS_WITH_WMASK(src, 0x3U, 6), 2376 SCRU_BASE + RK3588_CLKSEL_CON(2)); 2377 break; 2378 case SCMI_KEYLADDER_RNG: 2379 if (rate >= 175 * MHz) 2380 src = 0; 2381 else if (rate >= 116 * MHz) 2382 src = 1; 2383 else if (rate >= 58 * MHz) 2384 src = 2; 2385 else 2386 src = 3; 2387 2388 writel(BITS_WITH_WMASK(src, 0x3U, 8), 2389 SCRU_BASE + RK3588_CLKSEL_CON(2)); 2390 break; 2391 case SCMI_TCLK_WDT: 2392 break; 2393 case SCMI_HCLK_SD: 2394 case SCMI_HCLK_SECURE_NS: 2395 if (rate >= 150 * MHz) 2396 src = 0; 2397 else if (rate >= 100 * MHz) 2398 src = 1; 2399 else if (rate >= 50 * MHz) 2400 src = 2; 2401 else 2402 src = 3; 2403 writel(BITS_WITH_WMASK(src, 0x3U, 2), 2404 SCRU_BASE + RK3588_CLKSEL_CON(1)); 2405 break; 2406 default: 2407 return -ENOENT; 2408 } 2409 return 0; 2410 }; 2411 2412 /* A fake scmi driver for SPL/TPL where smccc agent is not available. */ 2413 static const struct clk_ops scmi_clk_ops = { 2414 .get_rate = rk3588_clk_scmi_get_rate, 2415 .set_rate = rk3588_clk_scmi_set_rate, 2416 }; 2417 2418 U_BOOT_DRIVER(scmi_clock) = { 2419 .name = "scmi_clk", 2420 .id = UCLASS_CLK, 2421 .ops = &scmi_clk_ops, 2422 }; 2423 #endif 2424 2425 #ifndef CONFIG_SPL_BUILD 2426 /** 2427 * soc_clk_dump() - Print clock frequencies 2428 * Returns zero on success 2429 * 2430 * Implementation for the clk dump command. 2431 */ 2432 int soc_clk_dump(void) 2433 { 2434 struct udevice *cru_dev; 2435 struct rk3588_clk_priv *priv; 2436 const struct rk3588_clk_info *clk_dump; 2437 struct clk clk; 2438 unsigned long clk_count = ARRAY_SIZE(clks_dump); 2439 unsigned long rate; 2440 int i, ret; 2441 2442 ret = uclass_get_device_by_driver(UCLASS_CLK, 2443 DM_GET_DRIVER(rockchip_rk3588_cru), 2444 &cru_dev); 2445 if (ret) { 2446 printf("%s failed to get cru device\n", __func__); 2447 return ret; 2448 } 2449 2450 priv = dev_get_priv(cru_dev); 2451 printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n", 2452 priv->sync_kernel ? "sync kernel" : "uboot", 2453 priv->armclk_enter_hz / 1000, 2454 priv->armclk_init_hz / 1000, 2455 priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0, 2456 priv->set_armclk_rate ? " KHz" : "N/A"); 2457 for (i = 0; i < clk_count; i++) { 2458 clk_dump = &clks_dump[i]; 2459 if (clk_dump->name) { 2460 clk.id = clk_dump->id; 2461 if (clk_dump->is_cru) 2462 ret = clk_request(cru_dev, &clk); 2463 if (ret < 0) 2464 return ret; 2465 2466 rate = clk_get_rate(&clk); 2467 clk_free(&clk); 2468 if (i == 0) { 2469 if (rate < 0) 2470 printf(" %s %s\n", clk_dump->name, 2471 "unknown"); 2472 else 2473 printf(" %s %lu KHz\n", clk_dump->name, 2474 rate / 1000); 2475 } else { 2476 if (rate < 0) 2477 printf(" %s %s\n", clk_dump->name, 2478 "unknown"); 2479 else 2480 printf(" %s %lu KHz\n", clk_dump->name, 2481 rate / 1000); 2482 } 2483 } 2484 } 2485 2486 return 0; 2487 } 2488 #endif 2489