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