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