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