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