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