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