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