1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2021 Fuzhou Rockchip Electronics Co., Ltd 4 * Author: Elaine Zhang <zhangqing@rock-chips.com> 5 */ 6 7 #include <common.h> 8 #include <bitfield.h> 9 #include <clk-uclass.h> 10 #include <dm.h> 11 #include <errno.h> 12 #include <syscon.h> 13 #include <asm/arch/clock.h> 14 #include <asm/arch/cru_rk3576.h> 15 #include <asm/arch/hardware.h> 16 #include <asm/io.h> 17 #include <dm/lists.h> 18 #include <dt-bindings/clock/rockchip,rk3576-cru.h> 19 20 DECLARE_GLOBAL_DATA_PTR; 21 22 #define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1)) 23 24 #if 1 25 static struct rockchip_pll_rate_table rk3576_24m_pll_rates[] = { 26 /* _mhz, _p, _m, _s, _k */ 27 RK3588_PLL_RATE(1500000000, 2, 250, 1, 0), 28 RK3588_PLL_RATE(1200000000, 1, 100, 1, 0), 29 RK3588_PLL_RATE(1188000000, 2, 198, 1, 0), 30 RK3588_PLL_RATE(1150000000, 3, 575, 2, 0), 31 RK3588_PLL_RATE(1100000000, 3, 550, 2, 0), 32 RK3588_PLL_RATE(1008000000, 2, 336, 2, 0), 33 RK3588_PLL_RATE(1000000000, 3, 500, 2, 0), 34 RK3588_PLL_RATE(900000000, 2, 300, 2, 0), 35 RK3588_PLL_RATE(850000000, 3, 425, 2, 0), 36 RK3588_PLL_RATE(816000000, 2, 272, 2, 0), 37 RK3588_PLL_RATE(786432000, 2, 262, 2, 9437), 38 RK3588_PLL_RATE(786000000, 1, 131, 2, 0), 39 RK3588_PLL_RATE(742500000, 4, 495, 2, 0), 40 RK3588_PLL_RATE(722534400, 8, 963, 2, 24850), 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 #else 48 static struct rockchip_pll_rate_table rk3576_26m_pll_rates[] = { 49 /* _mhz, _p, _m, _s, _k */ 50 RK3588_PLL_RATE(1188000000, 2, 183, 1, 50412), 51 RK3588_PLL_RATE(1100000000, 2, 338, 2, 30247), 52 RK3588_PLL_RATE(1014000000, 1, 156, 2, 0), 53 RK3588_PLL_RATE(1000000000, 2, 308, 2, 45371), 54 RK3588_PLL_RATE(858000000, 1, 132, 2, 0), 55 RK3588_PLL_RATE(806000000, 1, 124, 2, 0), 56 RK3588_PLL_RATE(786432000, 2, 242, 2, 64165), 57 RK3588_PLL_RATE(594000000, 2, 183, 2, 50412), 58 RK3588_PLL_RATE(297000000, 2, 183, 3, 50412), 59 RK3588_PLL_RATE(148500000, 2, 183, 4, 50412), 60 { /* sentinel */ }, 61 }; 62 #endif 63 64 static struct rockchip_pll_clock rk3576_pll_clks[] = { 65 [BPLL] = PLL(pll_rk3588, PLL_BPLL, RK3576_PLL_CON(0), 66 RK3576_BPLL_MODE_CON0, 0, 15, 0, 67 rk3576_24m_pll_rates), 68 [LPLL] = PLL(pll_rk3588, PLL_LPLL, RK3576_LPLL_CON(16), 69 RK3576_LPLL_MODE_CON0, 0, 15, 0, rk3576_24m_pll_rates), 70 [VPLL] = PLL(pll_rk3588, PLL_VPLL, RK3576_PLL_CON(88), 71 RK3576_LPLL_MODE_CON0, 4, 15, 0, rk3576_24m_pll_rates), 72 [AUPLL] = PLL(pll_rk3588, PLL_AUPLL, RK3576_PLL_CON(96), 73 RK3576_MODE_CON0, 6, 15, 0, rk3576_24m_pll_rates), 74 [CPLL] = PLL(pll_rk3588, PLL_CPLL, RK3576_PLL_CON(104), 75 RK3576_MODE_CON0, 8, 15, 0, rk3576_24m_pll_rates), 76 [GPLL] = PLL(pll_rk3588, PLL_GPLL, RK3576_PLL_CON(112), 77 RK3576_MODE_CON0, 2, 15, 0, rk3576_24m_pll_rates), 78 [PPLL] = PLL(pll_rk3588, PLL_PPLL, RK3576_PMU_PLL_CON(128), 79 RK3576_MODE_CON0, 10, 15, 0, rk3576_24m_pll_rates), 80 }; 81 82 #ifndef CONFIG_SPL_BUILD 83 #define RK3576_CLK_DUMP(_id, _name, _iscru) \ 84 { \ 85 .id = _id, \ 86 .name = _name, \ 87 .is_cru = _iscru, \ 88 } 89 90 static const struct rk3576_clk_info clks_dump[] = { 91 RK3576_CLK_DUMP(PLL_BPLL, "bpll", true), 92 RK3576_CLK_DUMP(PLL_LPLL, "lpll", true), 93 RK3576_CLK_DUMP(PLL_VPLL, "vpll", true), 94 RK3576_CLK_DUMP(PLL_AUPLL, "aupll", true), 95 RK3576_CLK_DUMP(PLL_CPLL, "cpll", true), 96 RK3576_CLK_DUMP(PLL_GPLL, "gpll", true), 97 RK3576_CLK_DUMP(PLL_PPLL, "ppll", true), 98 RK3576_CLK_DUMP(ACLK_BUS_ROOT, "aclk_bus_root", true), 99 RK3576_CLK_DUMP(PCLK_BUS_ROOT, "pclk_bus_root", true), 100 RK3576_CLK_DUMP(HCLK_BUS_ROOT, "hclk_bus_root", true), 101 RK3576_CLK_DUMP(ACLK_TOP, "aclk_top", true), 102 RK3576_CLK_DUMP(ACLK_TOP_MID, "aclk_top_mid", true), 103 RK3576_CLK_DUMP(PCLK_TOP_ROOT, "pclk_top", true), 104 RK3576_CLK_DUMP(HCLK_TOP, "hclk_top", true), 105 }; 106 #endif 107 108 #ifdef CONFIG_SPL_BUILD 109 #ifndef BITS_WITH_WMASK 110 #define BITS_WITH_WMASK(bits, msk, shift) \ 111 ((bits) << (shift)) | ((msk) << ((shift) + 16)) 112 #endif 113 #endif 114 115 #ifndef CONFIG_SPL_BUILD 116 /* 117 * 118 * rational_best_approximation(31415, 10000, 119 * (1 << 8) - 1, (1 << 5) - 1, &n, &d); 120 * 121 * you may look at given_numerator as a fixed point number, 122 * with the fractional part size described in given_denominator. 123 * 124 * for theoretical background, see: 125 * http://en.wikipedia.org/wiki/Continued_fraction 126 */ 127 static void rational_best_approximation(unsigned long given_numerator, 128 unsigned long given_denominator, 129 unsigned long max_numerator, 130 unsigned long max_denominator, 131 unsigned long *best_numerator, 132 unsigned long *best_denominator) 133 { 134 unsigned long n, d, n0, d0, n1, d1; 135 136 n = given_numerator; 137 d = given_denominator; 138 n0 = 0; 139 d1 = 0; 140 n1 = 1; 141 d0 = 1; 142 for (;;) { 143 unsigned long t, a; 144 145 if (n1 > max_numerator || d1 > max_denominator) { 146 n1 = n0; 147 d1 = d0; 148 break; 149 } 150 if (d == 0) 151 break; 152 t = d; 153 a = n / d; 154 d = n % d; 155 n = t; 156 t = n0 + a * n1; 157 n0 = n1; 158 n1 = t; 159 t = d0 + a * d1; 160 d0 = d1; 161 d1 = t; 162 } 163 *best_numerator = n1; 164 *best_denominator = d1; 165 } 166 #endif 167 168 static ulong rk3576_bus_get_clk(struct rk3576_clk_priv *priv, ulong clk_id) 169 { 170 struct rk3576_cru *cru = priv->cru; 171 u32 con, sel, div, rate; 172 173 switch (clk_id) { 174 case ACLK_BUS_ROOT: 175 con = readl(&cru->clksel_con[55]); 176 sel = (con & ACLK_BUS_ROOT_SEL_MASK) >> 177 ACLK_BUS_ROOT_SEL_SHIFT; 178 div = (con & ACLK_BUS_ROOT_DIV_MASK) >> 179 ACLK_BUS_ROOT_DIV_SHIFT; 180 if (sel == ACLK_BUS_ROOT_SEL_CPLL) 181 rate = DIV_TO_RATE(priv->cpll_hz , div); 182 else 183 rate = DIV_TO_RATE(priv->gpll_hz, div); 184 break; 185 case HCLK_BUS_ROOT: 186 con = readl(&cru->clksel_con[55]); 187 sel = (con & HCLK_BUS_ROOT_SEL_MASK) >> 188 HCLK_BUS_ROOT_SEL_SHIFT; 189 if (sel == HCLK_BUS_ROOT_SEL_200M) 190 rate = 198 * MHz; 191 else if (sel == HCLK_BUS_ROOT_SEL_100M) 192 rate = 100 * MHz; 193 else if (sel == HCLK_BUS_ROOT_SEL_50M) 194 rate = 50 * MHz; 195 else 196 rate = OSC_HZ; 197 break; 198 case PCLK_BUS_ROOT: 199 con = readl(&cru->clksel_con[55]); 200 sel = (con & PCLK_BUS_ROOT_SEL_MASK) >> 201 PCLK_BUS_ROOT_SEL_SHIFT; 202 if (sel == PCLK_BUS_ROOT_SEL_100M) 203 rate = 100 * MHz; 204 else if (sel == PCLK_BUS_ROOT_SEL_50M) 205 rate = 50 * MHz; 206 else 207 rate = OSC_HZ; 208 break; 209 default: 210 return -ENOENT; 211 } 212 213 return rate; 214 } 215 216 static ulong rk3576_bus_set_clk(struct rk3576_clk_priv *priv, 217 ulong clk_id, ulong rate) 218 { 219 struct rk3576_cru *cru = priv->cru; 220 int src_clk, src_clk_div; 221 222 switch (clk_id) { 223 case ACLK_BUS_ROOT: 224 if (!(priv->cpll_hz % rate)) { 225 src_clk = ACLK_BUS_ROOT_SEL_CPLL; 226 src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate); 227 } else { 228 src_clk = ACLK_BUS_ROOT_SEL_GPLL; 229 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); 230 } 231 rk_clrsetreg(&cru->clksel_con[55], 232 ACLK_BUS_ROOT_SEL_MASK, 233 src_clk << ACLK_BUS_ROOT_SEL_SHIFT); 234 assert(src_clk_div - 1 <= 31); 235 rk_clrsetreg(&cru->clksel_con[55], 236 ACLK_BUS_ROOT_DIV_MASK | 237 ACLK_BUS_ROOT_SEL_MASK, 238 (src_clk << 239 ACLK_BUS_ROOT_SEL_SHIFT) | 240 (src_clk_div - 1) << ACLK_BUS_ROOT_DIV_SHIFT); 241 break; 242 case HCLK_BUS_ROOT: 243 if (rate >= 198 * MHz) 244 src_clk = HCLK_BUS_ROOT_SEL_200M; 245 else if (rate >= 99 * MHz) 246 src_clk = HCLK_BUS_ROOT_SEL_100M; 247 else if (rate >= 50 * MHz) 248 src_clk = HCLK_BUS_ROOT_SEL_50M; 249 else 250 src_clk = HCLK_BUS_ROOT_SEL_OSC; 251 rk_clrsetreg(&cru->clksel_con[55], 252 HCLK_BUS_ROOT_SEL_MASK, 253 src_clk << HCLK_BUS_ROOT_SEL_SHIFT); 254 break; 255 case PCLK_BUS_ROOT: 256 if (rate >= 99 * MHz) 257 src_clk = PCLK_BUS_ROOT_SEL_100M; 258 else if (rate >= 50 * MHz) 259 src_clk = PCLK_BUS_ROOT_SEL_50M; 260 else 261 src_clk = PCLK_BUS_ROOT_SEL_OSC; 262 rk_clrsetreg(&cru->clksel_con[55], 263 PCLK_BUS_ROOT_SEL_MASK, 264 src_clk << PCLK_BUS_ROOT_SEL_SHIFT); 265 break; 266 default: 267 printf("do not support this center freq\n"); 268 return -EINVAL; 269 } 270 271 return rk3576_bus_get_clk(priv, clk_id); 272 } 273 274 static ulong rk3576_top_get_clk(struct rk3576_clk_priv *priv, ulong clk_id) 275 { 276 struct rk3576_cru *cru = priv->cru; 277 u32 con, sel, div, rate, prate; 278 279 switch (clk_id) { 280 case ACLK_TOP: 281 con = readl(&cru->clksel_con[9]); 282 div = (con & ACLK_TOP_DIV_MASK) >> 283 ACLK_TOP_DIV_SHIFT; 284 sel = (con & ACLK_TOP_SEL_MASK) >> 285 ACLK_TOP_SEL_SHIFT; 286 if (sel == ACLK_TOP_SEL_CPLL) 287 prate = priv->cpll_hz; 288 else if (sel == ACLK_TOP_SEL_AUPLL) 289 prate = priv->aupll_hz; 290 else 291 prate = priv->gpll_hz; 292 return DIV_TO_RATE(prate, div); 293 case ACLK_TOP_MID: 294 con = readl(&cru->clksel_con[10]); 295 div = (con & ACLK_TOP_MID_DIV_MASK) >> 296 ACLK_TOP_MID_DIV_SHIFT; 297 sel = (con & ACLK_TOP_MID_SEL_MASK) >> 298 ACLK_TOP_MID_SEL_SHIFT; 299 if (sel == ACLK_TOP_MID_SEL_CPLL) 300 prate = priv->cpll_hz; 301 else 302 prate = priv->gpll_hz; 303 return DIV_TO_RATE(prate, div); 304 case PCLK_TOP_ROOT: 305 con = readl(&cru->clksel_con[8]); 306 sel = (con & PCLK_TOP_SEL_MASK) >> PCLK_TOP_SEL_SHIFT; 307 if (sel == PCLK_TOP_SEL_100M) 308 rate = 100 * MHz; 309 else if (sel == PCLK_TOP_SEL_50M) 310 rate = 50 * MHz; 311 else 312 rate = OSC_HZ; 313 break; 314 case HCLK_TOP: 315 con = readl(&cru->clksel_con[19]); 316 sel = (con & HCLK_TOP_SEL_MASK) >> HCLK_TOP_SEL_SHIFT; 317 if (sel == HCLK_TOP_SEL_200M) 318 rate = 200 * MHz; 319 else if (sel == HCLK_TOP_SEL_100M) 320 rate = 100 * MHz; 321 else if (sel == HCLK_TOP_SEL_50M) 322 rate = 50 * MHz; 323 else 324 rate = OSC_HZ; 325 break; 326 default: 327 return -ENOENT; 328 } 329 330 return rate; 331 } 332 333 static ulong rk3576_top_set_clk(struct rk3576_clk_priv *priv, 334 ulong clk_id, ulong rate) 335 { 336 struct rk3576_cru *cru = priv->cru; 337 int src_clk, src_clk_div; 338 339 switch (clk_id) { 340 case ACLK_TOP: 341 if (!(priv->cpll_hz % rate)) { 342 src_clk = ACLK_TOP_SEL_CPLL; 343 src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate); 344 } else { 345 src_clk = ACLK_TOP_SEL_GPLL; 346 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); 347 } 348 assert(src_clk_div - 1 <= 31); 349 rk_clrsetreg(&cru->clksel_con[9], 350 ACLK_TOP_DIV_MASK | 351 ACLK_TOP_SEL_MASK, 352 (src_clk << 353 ACLK_TOP_SEL_SHIFT) | 354 (src_clk_div - 1) << ACLK_TOP_SEL_SHIFT); 355 break; 356 case ACLK_TOP_MID: 357 if (!(priv->cpll_hz % rate)) { 358 src_clk = ACLK_TOP_MID_SEL_CPLL; 359 src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate); 360 } else { 361 src_clk = ACLK_TOP_MID_SEL_GPLL; 362 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); 363 } 364 rk_clrsetreg(&cru->clksel_con[10], 365 ACLK_TOP_MID_DIV_MASK | 366 ACLK_TOP_MID_SEL_MASK, 367 (ACLK_TOP_MID_SEL_GPLL << 368 ACLK_TOP_MID_SEL_SHIFT) | 369 (src_clk_div - 1) << ACLK_TOP_MID_DIV_SHIFT); 370 break; 371 case PCLK_TOP_ROOT: 372 if (rate >= 99 * MHz) 373 src_clk = PCLK_TOP_SEL_100M; 374 else if (rate >= 50 * MHz) 375 src_clk = PCLK_TOP_SEL_50M; 376 else 377 src_clk = PCLK_TOP_SEL_OSC; 378 rk_clrsetreg(&cru->clksel_con[8], 379 PCLK_TOP_SEL_MASK, 380 src_clk << PCLK_TOP_SEL_SHIFT); 381 break; 382 case HCLK_TOP: 383 if (rate >= 198 * MHz) 384 src_clk = HCLK_TOP_SEL_200M; 385 else if (rate >= 99 * MHz) 386 src_clk = HCLK_TOP_SEL_100M; 387 else if (rate >= 50 * MHz) 388 src_clk = HCLK_TOP_SEL_50M; 389 else 390 src_clk = HCLK_TOP_SEL_OSC; 391 rk_clrsetreg(&cru->clksel_con[19], 392 HCLK_TOP_SEL_MASK, 393 src_clk << HCLK_TOP_SEL_SHIFT); 394 break; 395 default: 396 printf("do not support this top freq\n"); 397 return -EINVAL; 398 } 399 400 return rk3576_top_get_clk(priv, clk_id); 401 } 402 403 static ulong rk3576_i2c_get_clk(struct rk3576_clk_priv *priv, ulong clk_id) 404 { 405 struct rk3576_cru *cru = priv->cru; 406 u32 sel, con; 407 ulong rate; 408 409 switch (clk_id) { 410 case CLK_I2C0: 411 con = readl(&cru->pmuclksel_con[6]); 412 sel = (con & CLK_I2C0_SEL_MASK) >> CLK_I2C0_SEL_SHIFT; 413 break; 414 case CLK_I2C1: 415 con = readl(&cru->clksel_con[57]); 416 sel = (con & CLK_I2C1_SEL_MASK) >> CLK_I2C1_SEL_SHIFT; 417 break; 418 case CLK_I2C2: 419 con = readl(&cru->clksel_con[57]); 420 sel = (con & CLK_I2C2_SEL_MASK) >> CLK_I2C2_SEL_SHIFT; 421 break; 422 case CLK_I2C3: 423 con = readl(&cru->clksel_con[57]); 424 sel = (con & CLK_I2C3_SEL_MASK) >> CLK_I2C3_SEL_SHIFT; 425 break; 426 case CLK_I2C4: 427 con = readl(&cru->clksel_con[57]); 428 sel = (con & CLK_I2C4_SEL_MASK) >> CLK_I2C4_SEL_SHIFT; 429 break; 430 case CLK_I2C5: 431 con = readl(&cru->clksel_con[57]); 432 sel = (con & CLK_I2C5_SEL_MASK) >> CLK_I2C5_SEL_SHIFT; 433 break; 434 case CLK_I2C6: 435 con = readl(&cru->clksel_con[57]); 436 sel = (con & CLK_I2C6_SEL_MASK) >> CLK_I2C6_SEL_SHIFT; 437 break; 438 case CLK_I2C7: 439 con = readl(&cru->clksel_con[57]); 440 sel = (con & CLK_I2C7_SEL_MASK) >> CLK_I2C7_SEL_SHIFT; 441 break; 442 case CLK_I2C8: 443 con = readl(&cru->clksel_con[57]); 444 sel = (con & CLK_I2C8_SEL_MASK) >> CLK_I2C8_SEL_SHIFT; 445 break; 446 case CLK_I2C9: 447 con = readl(&cru->clksel_con[58]); 448 sel = (con & CLK_I2C9_SEL_MASK) >> CLK_I2C9_SEL_SHIFT; 449 break; 450 451 default: 452 return -ENOENT; 453 } 454 if (sel == CLK_I2C_SEL_200M) 455 rate = 200 * MHz; 456 else if (sel == CLK_I2C_SEL_100M) 457 rate = 100 * MHz; 458 else if (sel == CLK_I2C_SEL_50M) 459 rate = 50 * MHz; 460 else 461 rate = OSC_HZ; 462 463 return rate; 464 } 465 466 static ulong rk3576_i2c_set_clk(struct rk3576_clk_priv *priv, ulong clk_id, 467 ulong rate) 468 { 469 struct rk3576_cru *cru = priv->cru; 470 int src_clk; 471 472 if (rate >= 198 * MHz) 473 src_clk = CLK_I2C_SEL_200M; 474 else if (rate >= 99 * MHz) 475 src_clk = CLK_I2C_SEL_100M; 476 if (rate >= 50 * MHz) 477 src_clk = CLK_I2C_SEL_50M; 478 else 479 src_clk = CLK_I2C_SEL_OSC; 480 481 switch (clk_id) { 482 case CLK_I2C0: 483 rk_clrsetreg(&cru->pmuclksel_con[6], CLK_I2C0_SEL_MASK, 484 src_clk << CLK_I2C0_SEL_SHIFT); 485 break; 486 case CLK_I2C1: 487 rk_clrsetreg(&cru->clksel_con[57], CLK_I2C1_SEL_MASK, 488 src_clk << CLK_I2C1_SEL_SHIFT); 489 break; 490 case CLK_I2C2: 491 rk_clrsetreg(&cru->clksel_con[57], CLK_I2C2_SEL_MASK, 492 src_clk << CLK_I2C2_SEL_SHIFT); 493 break; 494 case CLK_I2C3: 495 rk_clrsetreg(&cru->clksel_con[57], CLK_I2C3_SEL_MASK, 496 src_clk << CLK_I2C3_SEL_SHIFT); 497 break; 498 case CLK_I2C4: 499 rk_clrsetreg(&cru->clksel_con[57], CLK_I2C4_SEL_MASK, 500 src_clk << CLK_I2C4_SEL_SHIFT); 501 break; 502 case CLK_I2C5: 503 rk_clrsetreg(&cru->clksel_con[57], CLK_I2C5_SEL_MASK, 504 src_clk << CLK_I2C5_SEL_SHIFT); 505 break; 506 case CLK_I2C6: 507 rk_clrsetreg(&cru->clksel_con[57], CLK_I2C6_SEL_MASK, 508 src_clk << CLK_I2C6_SEL_SHIFT); 509 break; 510 case CLK_I2C7: 511 rk_clrsetreg(&cru->clksel_con[57], CLK_I2C7_SEL_MASK, 512 src_clk << CLK_I2C7_SEL_SHIFT); 513 break; 514 case CLK_I2C8: 515 rk_clrsetreg(&cru->clksel_con[57], CLK_I2C8_SEL_MASK, 516 src_clk << CLK_I2C8_SEL_SHIFT); 517 case CLK_I2C9: 518 rk_clrsetreg(&cru->clksel_con[58], CLK_I2C9_SEL_MASK, 519 src_clk << CLK_I2C9_SEL_SHIFT); 520 break; 521 default: 522 return -ENOENT; 523 } 524 525 return rk3576_i2c_get_clk(priv, clk_id); 526 } 527 528 static ulong rk3576_spi_get_clk(struct rk3576_clk_priv *priv, ulong clk_id) 529 { 530 struct rk3576_cru *cru = priv->cru; 531 u32 sel, con; 532 533 switch (clk_id) { 534 case CLK_SPI0: 535 con = readl(&cru->clksel_con[70]); 536 sel = (con & CLK_SPI0_SEL_MASK) >> CLK_SPI0_SEL_SHIFT; 537 break; 538 case CLK_SPI1: 539 con = readl(&cru->clksel_con[71]); 540 sel = (con & CLK_SPI1_SEL_MASK) >> CLK_SPI1_SEL_SHIFT; 541 break; 542 case CLK_SPI2: 543 con = readl(&cru->clksel_con[71]); 544 sel = (con & CLK_SPI2_SEL_MASK) >> CLK_SPI2_SEL_SHIFT; 545 break; 546 case CLK_SPI3: 547 con = readl(&cru->clksel_con[71]); 548 sel = (con & CLK_SPI3_SEL_MASK) >> CLK_SPI3_SEL_SHIFT; 549 break; 550 case CLK_SPI4: 551 con = readl(&cru->clksel_con[71]); 552 sel = (con & CLK_SPI4_SEL_MASK) >> CLK_SPI4_SEL_SHIFT; 553 break; 554 default: 555 return -ENOENT; 556 } 557 558 switch (sel) { 559 case CLK_SPI_SEL_200M: 560 return 200 * MHz; 561 case CLK_SPI_SEL_100M: 562 return 100 * MHz; 563 case CLK_SPI_SEL_50M: 564 return 50 * MHz; 565 case CLK_SPI_SEL_OSC: 566 return OSC_HZ; 567 default: 568 return -ENOENT; 569 } 570 } 571 572 static ulong rk3576_spi_set_clk(struct rk3576_clk_priv *priv, 573 ulong clk_id, ulong rate) 574 { 575 struct rk3576_cru *cru = priv->cru; 576 int src_clk; 577 578 if (rate >= 198 * MHz) 579 src_clk = CLK_SPI_SEL_200M; 580 else if (rate >= 99 * MHz) 581 src_clk = CLK_SPI_SEL_100M; 582 else if (rate >= 50 * MHz) 583 src_clk = CLK_SPI_SEL_50M; 584 else 585 src_clk = CLK_SPI_SEL_OSC; 586 587 switch (clk_id) { 588 case CLK_SPI0: 589 rk_clrsetreg(&cru->clksel_con[70], 590 CLK_SPI0_SEL_MASK, 591 src_clk << CLK_SPI0_SEL_SHIFT); 592 break; 593 case CLK_SPI1: 594 rk_clrsetreg(&cru->clksel_con[71], 595 CLK_SPI1_SEL_MASK, 596 src_clk << CLK_SPI1_SEL_SHIFT); 597 break; 598 case CLK_SPI2: 599 rk_clrsetreg(&cru->clksel_con[71], 600 CLK_SPI2_SEL_MASK, 601 src_clk << CLK_SPI2_SEL_SHIFT); 602 break; 603 case CLK_SPI3: 604 rk_clrsetreg(&cru->clksel_con[71], 605 CLK_SPI3_SEL_MASK, 606 src_clk << CLK_SPI3_SEL_SHIFT); 607 break; 608 case CLK_SPI4: 609 rk_clrsetreg(&cru->clksel_con[71], 610 CLK_SPI4_SEL_MASK, 611 src_clk << CLK_SPI4_SEL_SHIFT); 612 break; 613 default: 614 return -ENOENT; 615 } 616 617 return rk3576_spi_get_clk(priv, clk_id); 618 } 619 620 static ulong rk3576_pwm_get_clk(struct rk3576_clk_priv *priv, ulong clk_id) 621 { 622 struct rk3576_cru *cru = priv->cru; 623 u32 sel, con; 624 625 switch (clk_id) { 626 case CLK_PWM1: 627 con = readl(&cru->clksel_con[71]); 628 sel = (con & CLK_PWM1_SEL_MASK) >> CLK_PWM1_SEL_SHIFT; 629 break; 630 case CLK_PWM2: 631 con = readl(&cru->clksel_con[74]); 632 sel = (con & CLK_PWM2_SEL_MASK) >> CLK_PWM2_SEL_SHIFT; 633 break; 634 case CLK_PMU1PWM: 635 con = readl(&cru->pmuclksel_con[5]); 636 sel = (con & CLK_PMU1PWM_SEL_MASK) >> CLK_PMU1PWM_SEL_SHIFT; 637 break; 638 default: 639 return -ENOENT; 640 } 641 642 switch (sel) { 643 case CLK_PWM_SEL_100M: 644 return 100 * MHz; 645 case CLK_PWM_SEL_50M: 646 return 50 * MHz; 647 case CLK_PWM_SEL_OSC: 648 return OSC_HZ; 649 default: 650 return -ENOENT; 651 } 652 } 653 654 static ulong rk3576_pwm_set_clk(struct rk3576_clk_priv *priv, 655 ulong clk_id, ulong rate) 656 { 657 struct rk3576_cru *cru = priv->cru; 658 int src_clk; 659 660 if (rate >= 99 * MHz) 661 src_clk = CLK_PWM_SEL_100M; 662 else if (rate >= 50 * MHz) 663 src_clk = CLK_PWM_SEL_50M; 664 else 665 src_clk = CLK_PWM_SEL_OSC; 666 667 switch (clk_id) { 668 case CLK_PWM1: 669 rk_clrsetreg(&cru->clksel_con[71], 670 CLK_PWM1_SEL_MASK, 671 src_clk << CLK_PWM1_SEL_SHIFT); 672 break; 673 case CLK_PWM2: 674 rk_clrsetreg(&cru->clksel_con[74], 675 CLK_PWM2_SEL_MASK, 676 src_clk << CLK_PWM2_SEL_SHIFT); 677 break; 678 case CLK_PMU1PWM: 679 rk_clrsetreg(&cru->pmuclksel_con[5], 680 CLK_PMU1PWM_SEL_MASK, 681 src_clk << CLK_PMU1PWM_SEL_SHIFT); 682 break; 683 default: 684 return -ENOENT; 685 } 686 687 return rk3576_pwm_get_clk(priv, clk_id); 688 } 689 690 static ulong rk3576_adc_get_clk(struct rk3576_clk_priv *priv, ulong clk_id) 691 { 692 struct rk3576_cru *cru = priv->cru; 693 u32 div, sel, con, prate; 694 695 switch (clk_id) { 696 case CLK_SARADC: 697 con = readl(&cru->clksel_con[58]); 698 div = (con & CLK_SARADC_DIV_MASK) >> CLK_SARADC_DIV_SHIFT; 699 sel = (con & CLK_SARADC_SEL_MASK) >> 700 CLK_SARADC_SEL_SHIFT; 701 if (sel == CLK_SARADC_SEL_OSC) 702 prate = OSC_HZ; 703 else 704 prate = priv->gpll_hz; 705 return DIV_TO_RATE(prate, div); 706 case CLK_TSADC: 707 con = readl(&cru->clksel_con[59]); 708 div = (con & CLK_TSADC_DIV_MASK) >> 709 CLK_TSADC_DIV_SHIFT; 710 prate = OSC_HZ; 711 return DIV_TO_RATE(prate, div); 712 default: 713 return -ENOENT; 714 } 715 } 716 717 static ulong rk3576_adc_set_clk(struct rk3576_clk_priv *priv, 718 ulong clk_id, ulong rate) 719 { 720 struct rk3576_cru *cru = priv->cru; 721 int src_clk_div; 722 723 switch (clk_id) { 724 case CLK_SARADC: 725 if (!(OSC_HZ % rate)) { 726 src_clk_div = DIV_ROUND_UP(OSC_HZ, rate); 727 assert(src_clk_div - 1 <= 255); 728 rk_clrsetreg(&cru->clksel_con[58], 729 CLK_SARADC_SEL_MASK | 730 CLK_SARADC_DIV_MASK, 731 (CLK_SARADC_SEL_OSC << 732 CLK_SARADC_SEL_SHIFT) | 733 (src_clk_div - 1) << 734 CLK_SARADC_DIV_SHIFT); 735 } else { 736 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); 737 assert(src_clk_div - 1 <= 255); 738 rk_clrsetreg(&cru->clksel_con[59], 739 CLK_SARADC_SEL_MASK | 740 CLK_SARADC_DIV_MASK, 741 (CLK_SARADC_SEL_GPLL << 742 CLK_SARADC_SEL_SHIFT) | 743 (src_clk_div - 1) << 744 CLK_SARADC_DIV_SHIFT); 745 } 746 break; 747 case CLK_TSADC: 748 src_clk_div = DIV_ROUND_UP(OSC_HZ, rate); 749 assert(src_clk_div - 1 <= 255); 750 rk_clrsetreg(&cru->clksel_con[58], 751 CLK_TSADC_DIV_MASK, 752 (src_clk_div - 1) << 753 CLK_TSADC_DIV_SHIFT); 754 break; 755 default: 756 return -ENOENT; 757 } 758 return rk3576_adc_get_clk(priv, clk_id); 759 } 760 761 static ulong rk3576_mmc_get_clk(struct rk3576_clk_priv *priv, ulong clk_id) 762 { 763 struct rk3576_cru *cru = priv->cru; 764 u32 sel, con, prate, div = 0; 765 766 switch (clk_id) { 767 case CCLK_SRC_SDIO: 768 case HCLK_SDIO: 769 con = readl(&cru->clksel_con[104]); 770 div = (con & CCLK_SDIO_SRC_DIV_MASK) >> CCLK_SDIO_SRC_DIV_SHIFT; 771 sel = (con & CCLK_SDIO_SRC_SEL_MASK) >> 772 CCLK_SDIO_SRC_SEL_SHIFT; 773 if (sel == CCLK_SDIO_SRC_SEL_GPLL) 774 prate = priv->gpll_hz; 775 else if (sel == CCLK_SDIO_SRC_SEL_CPLL) 776 prate = priv->cpll_hz; 777 else 778 prate = OSC_HZ; 779 return DIV_TO_RATE(prate, div); 780 case CCLK_SRC_SDMMC0: 781 case HCLK_SDMMC0: 782 con = readl(&cru->clksel_con[105]); 783 div = (con & CCLK_SDMMC0_SRC_DIV_MASK) >> CCLK_SDMMC0_SRC_DIV_SHIFT; 784 sel = (con & CCLK_SDMMC0_SRC_SEL_MASK) >> 785 CCLK_SDMMC0_SRC_SEL_SHIFT; 786 if (sel == CCLK_SDMMC0_SRC_SEL_GPLL) 787 prate = priv->gpll_hz; 788 else if (sel == CCLK_SDMMC0_SRC_SEL_CPLL) 789 prate = priv->cpll_hz; 790 else 791 prate = OSC_HZ; 792 return DIV_TO_RATE(prate, div); 793 case CCLK_SRC_EMMC: 794 case HCLK_EMMC: 795 con = readl(&cru->clksel_con[89]); 796 div = (con & CCLK_EMMC_DIV_MASK) >> CCLK_EMMC_DIV_SHIFT; 797 sel = (con & CCLK_EMMC_SEL_MASK) >> 798 CCLK_EMMC_SEL_SHIFT; 799 if (sel == CCLK_EMMC_SEL_GPLL) 800 prate = priv->gpll_hz; 801 else if (sel == CCLK_EMMC_SEL_CPLL) 802 prate = priv->cpll_hz; 803 else 804 prate = OSC_HZ; 805 return DIV_TO_RATE(prate, div); 806 case BCLK_EMMC: 807 con = readl(&cru->clksel_con[90]); 808 sel = (con & BCLK_EMMC_SEL_MASK) >> 809 BCLK_EMMC_SEL_SHIFT; 810 if (sel == BCLK_EMMC_SEL_200M) 811 prate = 200 * MHz; 812 else if (sel == BCLK_EMMC_SEL_100M) 813 prate = 100 * MHz; 814 else if (sel == BCLK_EMMC_SEL_50M) 815 prate = 50 * MHz; 816 else 817 prate = OSC_HZ; 818 return DIV_TO_RATE(prate, div); 819 case SCLK_FSPI_X2: 820 con = readl(&cru->clksel_con[89]); 821 div = (con & SCLK_FSPI_DIV_MASK) >> SCLK_FSPI_DIV_SHIFT; 822 sel = (con & SCLK_FSPI_SEL_MASK) >> 823 SCLK_FSPI_SEL_SHIFT; 824 if (sel == SCLK_FSPI_SEL_GPLL) 825 prate = priv->gpll_hz; 826 else if (sel == SCLK_FSPI_SEL_CPLL) 827 prate = priv->cpll_hz; 828 else 829 prate = OSC_HZ; 830 return DIV_TO_RATE(prate, div); 831 case SCLK_FSPI1_X2: 832 con = readl(&cru->clksel_con[106]); 833 div = (con & SCLK_FSPI_DIV_MASK) >> SCLK_FSPI_DIV_SHIFT; 834 sel = (con & SCLK_FSPI_SEL_MASK) >> 835 SCLK_FSPI_SEL_SHIFT; 836 if (sel == SCLK_FSPI_SEL_GPLL) 837 prate = priv->gpll_hz; 838 else if (sel == SCLK_FSPI_SEL_CPLL) 839 prate = priv->cpll_hz; 840 else 841 prate = OSC_HZ; 842 return DIV_TO_RATE(prate, div); 843 case DCLK_DECOM: 844 con = readl(&cru->clksel_con[72]); 845 div = (con & DCLK_DECOM_DIV_MASK) >> DCLK_DECOM_DIV_SHIFT; 846 sel = (con & DCLK_DECOM_SEL_MASK) >> DCLK_DECOM_SEL_SHIFT; 847 if (sel == DCLK_DECOM_SEL_SPLL) 848 prate = priv->spll_hz; 849 else 850 prate = priv->gpll_hz; 851 return DIV_TO_RATE(prate, div); 852 853 default: 854 return -ENOENT; 855 } 856 } 857 858 static ulong rk3576_mmc_set_clk(struct rk3576_clk_priv *priv, 859 ulong clk_id, ulong rate) 860 { 861 struct rk3576_cru *cru = priv->cru; 862 int src_clk, div = 0; 863 864 switch (clk_id) { 865 case CCLK_SRC_SDIO: 866 case CCLK_SRC_SDMMC0: 867 case CCLK_SRC_EMMC: 868 case SCLK_FSPI_X2: 869 case SCLK_FSPI1_X2: 870 case HCLK_SDMMC0: 871 case HCLK_EMMC: 872 case HCLK_SDIO: 873 if (!(OSC_HZ % rate)) { 874 src_clk = SCLK_FSPI_SEL_OSC; 875 div = DIV_ROUND_UP(OSC_HZ, rate); 876 } else if (!(priv->cpll_hz % rate)) { 877 src_clk = SCLK_FSPI_SEL_CPLL; 878 div = DIV_ROUND_UP(priv->cpll_hz, rate); 879 } else { 880 src_clk = SCLK_FSPI_SEL_GPLL; 881 div = DIV_ROUND_UP(priv->gpll_hz, rate); 882 } 883 break; 884 case BCLK_EMMC: 885 if (rate >= 198 * MHz) 886 src_clk = BCLK_EMMC_SEL_200M; 887 else if (rate >= 99 * MHz) 888 src_clk = BCLK_EMMC_SEL_100M; 889 else if (rate >= 50 * MHz) 890 src_clk = BCLK_EMMC_SEL_50M; 891 else 892 src_clk = BCLK_EMMC_SEL_OSC; 893 break; 894 case DCLK_DECOM: 895 if (!(priv->spll_hz % rate)) { 896 src_clk = DCLK_DECOM_SEL_SPLL; 897 div = DIV_ROUND_UP(priv->spll_hz, rate); 898 } else { 899 src_clk = DCLK_DECOM_SEL_GPLL; 900 div = DIV_ROUND_UP(priv->gpll_hz, rate); 901 } 902 break; 903 default: 904 return -ENOENT; 905 } 906 907 switch (clk_id) { 908 case CCLK_SRC_SDIO: 909 case HCLK_SDIO: 910 rk_clrsetreg(&cru->clksel_con[104], 911 CCLK_SDIO_SRC_SEL_MASK | 912 CCLK_SDIO_SRC_DIV_MASK, 913 (src_clk << CCLK_SDIO_SRC_SEL_SHIFT) | 914 (div - 1) << CCLK_SDIO_SRC_DIV_SHIFT); 915 break; 916 case CCLK_SRC_SDMMC0: 917 case HCLK_SDMMC0: 918 rk_clrsetreg(&cru->clksel_con[105], 919 CCLK_SDMMC0_SRC_SEL_MASK | 920 CCLK_SDMMC0_SRC_DIV_MASK, 921 (src_clk << CCLK_SDMMC0_SRC_SEL_SHIFT) | 922 (div - 1) << CCLK_SDMMC0_SRC_DIV_SHIFT); 923 break; 924 case CCLK_SRC_EMMC: 925 case HCLK_EMMC: 926 rk_clrsetreg(&cru->clksel_con[89], 927 CCLK_EMMC_DIV_MASK | 928 CCLK_EMMC_SEL_MASK, 929 (src_clk << CCLK_EMMC_SEL_SHIFT) | 930 (div - 1) << CCLK_EMMC_DIV_SHIFT); 931 break; 932 case SCLK_FSPI_X2: 933 rk_clrsetreg(&cru->clksel_con[89], 934 SCLK_FSPI_DIV_MASK | 935 SCLK_FSPI_SEL_MASK, 936 (src_clk << SCLK_FSPI_SEL_SHIFT) | 937 (div - 1) << SCLK_FSPI_DIV_SHIFT); 938 break; 939 case SCLK_FSPI1_X2: 940 rk_clrsetreg(&cru->clksel_con[106], 941 SCLK_FSPI_DIV_MASK | 942 SCLK_FSPI_SEL_MASK, 943 (src_clk << SCLK_FSPI_SEL_SHIFT) | 944 (div - 1) << SCLK_FSPI_DIV_SHIFT); 945 break; 946 case BCLK_EMMC: 947 rk_clrsetreg(&cru->clksel_con[90], 948 BCLK_EMMC_SEL_MASK, 949 src_clk << BCLK_EMMC_SEL_SHIFT); 950 break; 951 case DCLK_DECOM: 952 rk_clrsetreg(&cru->clksel_con[72], 953 DCLK_DECOM_DIV_MASK | 954 DCLK_DECOM_SEL_MASK, 955 (src_clk << DCLK_DECOM_SEL_SHIFT) | 956 (div - 1) << DCLK_DECOM_DIV_SHIFT); 957 break; 958 959 default: 960 return -ENOENT; 961 } 962 963 return rk3576_mmc_get_clk(priv, clk_id); 964 } 965 966 #ifndef CONFIG_SPL_BUILD 967 968 static ulong rk3576_aclk_vop_get_clk(struct rk3576_clk_priv *priv, ulong clk_id) 969 { 970 struct rk3576_cru *cru = priv->cru; 971 u32 div, sel, con, parent = 0; 972 973 switch (clk_id) { 974 case ACLK_VOP_ROOT: 975 case ACLK_VOP: 976 con = readl(&cru->clksel_con[144]); 977 div = (con & ACLK_VOP_ROOT_DIV_MASK) >> ACLK_VOP_ROOT_DIV_SHIFT; 978 sel = (con & ACLK_VOP_ROOT_SEL_MASK) >> ACLK_VOP_ROOT_SEL_SHIFT; 979 if (sel == ACLK_VOP_ROOT_SEL_GPLL) 980 parent = priv->gpll_hz; 981 else if (sel == ACLK_VOP_ROOT_SEL_CPLL) 982 parent = priv->cpll_hz; 983 else if (sel == ACLK_VOP_ROOT_SEL_AUPLL) 984 parent = priv->aupll_hz; 985 else if (sel == ACLK_VOP_ROOT_SEL_SPLL) 986 parent = priv->spll_hz; 987 else if (sel == ACLK_VOP_ROOT_SEL_LPLL) 988 parent = priv->lpll_hz / 2; 989 return DIV_TO_RATE(parent, div); 990 case ACLK_VO0_ROOT: 991 con = readl(&cru->clksel_con[149]); 992 div = (con & ACLK_VO0_ROOT_DIV_MASK) >> ACLK_VO0_ROOT_DIV_SHIFT; 993 sel = (con & ACLK_VO0_ROOT_SEL_MASK) >> ACLK_VO0_ROOT_SEL_SHIFT; 994 if (sel == ACLK_VO0_ROOT_SEL_GPLL) 995 parent = priv->gpll_hz; 996 else if (sel == ACLK_VO0_ROOT_SEL_CPLL) 997 parent = priv->cpll_hz; 998 else if (sel == ACLK_VO0_ROOT_SEL_LPLL) 999 parent = priv->lpll_hz / 2; 1000 else if (sel == ACLK_VO0_ROOT_SEL_BPLL) 1001 parent = priv->bpll_hz / 4; 1002 return DIV_TO_RATE(parent, div); 1003 case ACLK_VO1_ROOT: 1004 con = readl(&cru->clksel_con[158]); 1005 div = (con & ACLK_VO0_ROOT_DIV_MASK) >> ACLK_VO0_ROOT_DIV_SHIFT; 1006 sel = (con & ACLK_VO0_ROOT_SEL_MASK) >> ACLK_VO0_ROOT_SEL_SHIFT; 1007 if (sel == ACLK_VO0_ROOT_SEL_GPLL) 1008 parent = priv->gpll_hz; 1009 else if (sel == ACLK_VO0_ROOT_SEL_CPLL) 1010 parent = priv->cpll_hz; 1011 else if (sel == ACLK_VO0_ROOT_SEL_LPLL) 1012 parent = priv->lpll_hz / 2; 1013 else if (sel == ACLK_VO0_ROOT_SEL_BPLL) 1014 parent = priv->bpll_hz / 4; 1015 return DIV_TO_RATE(parent, div); 1016 case HCLK_VOP_ROOT: 1017 con = readl(&cru->clksel_con[144]); 1018 sel = (con & HCLK_VOP_ROOT_SEL_MASK) >> HCLK_VOP_ROOT_SEL_SHIFT; 1019 if (sel == HCLK_VOP_ROOT_SEL_200M) 1020 return 200 * MHz; 1021 else if (sel == HCLK_VOP_ROOT_SEL_100M) 1022 return 100 * MHz; 1023 else if (sel == HCLK_VOP_ROOT_SEL_50M) 1024 return 50 * MHz; 1025 else 1026 return OSC_HZ; 1027 case PCLK_VOP_ROOT: 1028 con = readl(&cru->clksel_con[144]); 1029 sel = (con & PCLK_VOP_ROOT_SEL_MASK) >> PCLK_VOP_ROOT_SEL_SHIFT; 1030 if (sel == PCLK_VOP_ROOT_SEL_100M) 1031 return 100 * MHz; 1032 else if (sel == PCLK_VOP_ROOT_SEL_50M) 1033 return 50 * MHz; 1034 else 1035 return OSC_HZ; 1036 1037 default: 1038 return -ENOENT; 1039 } 1040 } 1041 1042 static ulong rk3576_aclk_vop_set_clk(struct rk3576_clk_priv *priv, 1043 ulong clk_id, ulong rate) 1044 { 1045 struct rk3576_cru *cru = priv->cru; 1046 int src_clk, div; 1047 1048 switch (clk_id) { 1049 case ACLK_VOP_ROOT: 1050 case ACLK_VOP: 1051 if (rate == 700 * MHz) { 1052 src_clk = ACLK_VOP_ROOT_SEL_SPLL; 1053 div = 1; 1054 } else if (!(priv->cpll_hz % rate)) { 1055 src_clk = ACLK_VOP_ROOT_SEL_CPLL; 1056 div = DIV_ROUND_UP(priv->cpll_hz, rate); 1057 } else { 1058 src_clk = ACLK_VOP_ROOT_SEL_GPLL; 1059 div = DIV_ROUND_UP(priv->gpll_hz, rate); 1060 } 1061 rk_clrsetreg(&cru->clksel_con[144], 1062 ACLK_VOP_ROOT_DIV_MASK | 1063 ACLK_VOP_ROOT_SEL_MASK, 1064 (src_clk << ACLK_VOP_ROOT_SEL_SHIFT) | 1065 (div - 1) << ACLK_VOP_ROOT_DIV_SHIFT); 1066 break; 1067 case ACLK_VO0_ROOT: 1068 if (!(priv->cpll_hz % rate)) { 1069 src_clk = ACLK_VO0_ROOT_SEL_CPLL; 1070 div = DIV_ROUND_UP(priv->cpll_hz, rate); 1071 } else { 1072 src_clk = ACLK_VO0_ROOT_SEL_GPLL; 1073 div = DIV_ROUND_UP(priv->gpll_hz, rate); 1074 } 1075 rk_clrsetreg(&cru->clksel_con[149], 1076 ACLK_VO0_ROOT_DIV_MASK | 1077 ACLK_VO0_ROOT_SEL_MASK, 1078 (src_clk << ACLK_VO0_ROOT_SEL_SHIFT) | 1079 (div - 1) << ACLK_VO0_ROOT_DIV_SHIFT); 1080 break; 1081 case ACLK_VO1_ROOT: 1082 if (!(priv->cpll_hz % rate)) { 1083 src_clk = ACLK_VO0_ROOT_SEL_CPLL; 1084 div = DIV_ROUND_UP(priv->cpll_hz, rate); 1085 } else { 1086 src_clk = ACLK_VO0_ROOT_SEL_GPLL; 1087 div = DIV_ROUND_UP(priv->gpll_hz, rate); 1088 } 1089 rk_clrsetreg(&cru->clksel_con[158], 1090 ACLK_VO0_ROOT_DIV_MASK | 1091 ACLK_VO0_ROOT_SEL_MASK, 1092 (src_clk << ACLK_VO0_ROOT_SEL_SHIFT) | 1093 (div - 1) << ACLK_VO0_ROOT_DIV_SHIFT); 1094 break; 1095 case HCLK_VOP_ROOT: 1096 if (rate == 200 * MHz) 1097 src_clk = HCLK_VOP_ROOT_SEL_200M; 1098 else if (rate == 100 * MHz) 1099 src_clk = HCLK_VOP_ROOT_SEL_100M; 1100 else if (rate == 50 * MHz) 1101 src_clk = HCLK_VOP_ROOT_SEL_50M; 1102 else 1103 src_clk = HCLK_VOP_ROOT_SEL_OSC; 1104 rk_clrsetreg(&cru->clksel_con[144], 1105 HCLK_VOP_ROOT_SEL_MASK, 1106 src_clk << HCLK_VOP_ROOT_SEL_SHIFT); 1107 break; 1108 case PCLK_VOP_ROOT: 1109 if (rate == 100 * MHz) 1110 src_clk = PCLK_VOP_ROOT_SEL_100M; 1111 else if (rate == 50 * MHz) 1112 src_clk = PCLK_VOP_ROOT_SEL_50M; 1113 else 1114 src_clk = PCLK_VOP_ROOT_SEL_OSC; 1115 rk_clrsetreg(&cru->clksel_con[144], 1116 PCLK_VOP_ROOT_SEL_MASK, 1117 src_clk << PCLK_VOP_ROOT_SEL_SHIFT); 1118 break; 1119 1120 default: 1121 return -ENOENT; 1122 } 1123 1124 return rk3576_aclk_vop_get_clk(priv, clk_id); 1125 } 1126 1127 static ulong rk3576_dclk_vop_get_clk(struct rk3576_clk_priv *priv, ulong clk_id) 1128 { 1129 struct rk3576_cru *cru = priv->cru; 1130 u32 div, sel, con, parent; 1131 1132 switch (clk_id) { 1133 case DCLK_VP0: 1134 case DCLK_VP0_SRC: 1135 con = readl(&cru->clksel_con[145]); 1136 div = (con & DCLK0_VOP_SRC_DIV_MASK) >> DCLK0_VOP_SRC_DIV_SHIFT; 1137 sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT; 1138 break; 1139 case DCLK_VP1: 1140 case DCLK_VP1_SRC: 1141 con = readl(&cru->clksel_con[146]); 1142 div = (con & DCLK0_VOP_SRC_DIV_MASK) >> DCLK0_VOP_SRC_DIV_SHIFT; 1143 sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT; 1144 break; 1145 case DCLK_VP2: 1146 case DCLK_VP2_SRC: 1147 con = readl(&cru->clksel_con[147]); 1148 div = (con & DCLK0_VOP_SRC_DIV_MASK) >> DCLK0_VOP_SRC_DIV_SHIFT; 1149 sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT; 1150 break; 1151 default: 1152 return -ENOENT; 1153 } 1154 1155 if (sel == DCLK_VOP_SRC_SEL_VPLL) 1156 parent = priv->vpll_hz; 1157 else if (sel == DCLK_VOP_SRC_SEL_BPLL) 1158 parent = priv->bpll_hz / 4; 1159 else if (sel == DCLK_VOP_SRC_SEL_LPLL) 1160 parent = priv->lpll_hz / 2; 1161 else if (sel == DCLK_VOP_SRC_SEL_GPLL) 1162 parent = priv->gpll_hz; 1163 else 1164 parent = priv->cpll_hz; 1165 1166 return DIV_TO_RATE(parent, div); 1167 } 1168 1169 #define RK3576_VOP_PLL_LIMIT_FREQ 600000000 1170 1171 static ulong rk3576_dclk_vop_set_clk(struct rk3576_clk_priv *priv, 1172 ulong clk_id, ulong rate) 1173 { 1174 struct rk3576_cru *cru = priv->cru; 1175 ulong pll_rate, now, best_rate = 0; 1176 u32 i, conid, con, sel, div, best_div = 0, best_sel = 0; 1177 u32 mask, div_shift, sel_shift; 1178 1179 switch (clk_id) { 1180 case DCLK_VP0: 1181 case DCLK_VP0_SRC: 1182 conid = 145; 1183 con = readl(&cru->clksel_con[conid]); 1184 sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT; 1185 mask = DCLK0_VOP_SRC_SEL_MASK | DCLK0_VOP_SRC_DIV_MASK; 1186 div_shift = DCLK0_VOP_SRC_DIV_SHIFT; 1187 sel_shift = DCLK0_VOP_SRC_SEL_SHIFT; 1188 break; 1189 case DCLK_VP1: 1190 case DCLK_VP1_SRC: 1191 conid = 146; 1192 con = readl(&cru->clksel_con[conid]); 1193 sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT; 1194 mask = DCLK0_VOP_SRC_SEL_MASK | DCLK0_VOP_SRC_DIV_MASK; 1195 div_shift = DCLK0_VOP_SRC_DIV_SHIFT; 1196 sel_shift = DCLK0_VOP_SRC_SEL_SHIFT; 1197 break; 1198 case DCLK_VP2: 1199 case DCLK_VP2_SRC: 1200 conid = 147; 1201 con = readl(&cru->clksel_con[conid]); 1202 sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT; 1203 mask = DCLK0_VOP_SRC_SEL_MASK | DCLK0_VOP_SRC_DIV_MASK; 1204 div_shift = DCLK0_VOP_SRC_DIV_SHIFT; 1205 sel_shift = DCLK0_VOP_SRC_SEL_SHIFT; 1206 break; 1207 default: 1208 return -ENOENT; 1209 } 1210 1211 if (sel == DCLK_VOP_SRC_SEL_VPLL) { 1212 pll_rate = rockchip_pll_get_rate(&rk3576_pll_clks[VPLL], 1213 priv->cru, VPLL); 1214 if (pll_rate >= RK3576_VOP_PLL_LIMIT_FREQ && pll_rate % rate == 0) { 1215 div = DIV_ROUND_UP(pll_rate, rate); 1216 rk_clrsetreg(&cru->clksel_con[conid], 1217 mask, 1218 DCLK_VOP_SRC_SEL_VPLL << sel_shift | 1219 ((div - 1) << div_shift)); 1220 } else { 1221 div = DIV_ROUND_UP(RK3576_VOP_PLL_LIMIT_FREQ, rate); 1222 if (div % 2) 1223 div = div + 1; 1224 rk_clrsetreg(&cru->clksel_con[conid], 1225 mask, 1226 DCLK_VOP_SRC_SEL_VPLL << sel_shift | 1227 ((div - 1) << div_shift)); 1228 rockchip_pll_set_rate(&rk3576_pll_clks[VPLL], 1229 priv->cru, VPLL, div * rate); 1230 priv->vpll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[VPLL], 1231 priv->cru, VPLL); 1232 } 1233 } else { 1234 for (i = 0; i <= DCLK_VOP_SRC_SEL_LPLL; i++) { 1235 switch (i) { 1236 case DCLK_VOP_SRC_SEL_GPLL: 1237 pll_rate = priv->gpll_hz; 1238 break; 1239 case DCLK_VOP_SRC_SEL_CPLL: 1240 pll_rate = priv->cpll_hz; 1241 break; 1242 case DCLK_VOP_SRC_SEL_BPLL: 1243 pll_rate = 0; 1244 break; 1245 case DCLK_VOP_SRC_SEL_LPLL: 1246 pll_rate = 0; 1247 break; 1248 case DCLK_VOP_SRC_SEL_VPLL: 1249 pll_rate = 0; 1250 break; 1251 default: 1252 printf("do not support this vop pll sel\n"); 1253 return -EINVAL; 1254 } 1255 1256 div = DIV_ROUND_UP(pll_rate, rate); 1257 if (div > 255) 1258 continue; 1259 now = pll_rate / div; 1260 if (abs(rate - now) < abs(rate - best_rate)) { 1261 best_rate = now; 1262 best_div = div; 1263 best_sel = i; 1264 } 1265 debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n", 1266 pll_rate, best_rate, best_div, best_sel); 1267 } 1268 1269 if (best_rate) { 1270 rk_clrsetreg(&cru->clksel_con[conid], 1271 mask, 1272 best_sel << sel_shift | 1273 (best_div - 1) << div_shift); 1274 } else { 1275 printf("do not support this vop freq %lu\n", rate); 1276 return -EINVAL; 1277 } 1278 } 1279 return rk3576_dclk_vop_get_clk(priv, clk_id); 1280 } 1281 1282 static ulong rk3576_clk_csihost_get_clk(struct rk3576_clk_priv *priv, ulong clk_id) 1283 { 1284 struct rk3576_cru *cru = priv->cru; 1285 u32 div, sel, con, parent; 1286 1287 switch (clk_id) { 1288 case CLK_DSIHOST0: 1289 con = readl(&cru->clksel_con[151]); 1290 div = (con & CLK_DSIHOST0_DIV_MASK) >> CLK_DSIHOST0_DIV_SHIFT; 1291 sel = (con & CLK_DSIHOST0_SEL_MASK) >> CLK_DSIHOST0_SEL_SHIFT; 1292 break; 1293 default: 1294 return -ENOENT; 1295 } 1296 1297 if (sel == CLK_DSIHOST0_SEL_VPLL) 1298 parent = priv->vpll_hz; 1299 else if (sel == CLK_DSIHOST0_SEL_BPLL) 1300 parent = priv->bpll_hz / 4; 1301 else if (sel == CLK_DSIHOST0_SEL_LPLL) 1302 parent = priv->lpll_hz / 2; 1303 else if (sel == CLK_DSIHOST0_SEL_GPLL) 1304 parent = priv->gpll_hz; 1305 else if (sel == CLK_DSIHOST0_SEL_SPLL) 1306 parent = priv->spll_hz; 1307 else 1308 parent = priv->cpll_hz; 1309 1310 return DIV_TO_RATE(parent, div); 1311 } 1312 1313 static ulong rk3576_clk_csihost_set_clk(struct rk3576_clk_priv *priv, 1314 ulong clk_id, ulong rate) 1315 { 1316 struct rk3576_cru *cru = priv->cru; 1317 ulong pll_rate, now, best_rate = 0; 1318 u32 i, con, div, best_div = 0, best_sel = 0; 1319 u32 mask, div_shift, sel_shift; 1320 1321 switch (clk_id) { 1322 case CLK_DSIHOST0: 1323 con = 151; 1324 mask = CLK_DSIHOST0_SEL_MASK | CLK_DSIHOST0_DIV_MASK; 1325 div_shift = CLK_DSIHOST0_DIV_SHIFT; 1326 sel_shift = CLK_DSIHOST0_SEL_SHIFT; 1327 break; 1328 default: 1329 return -ENOENT; 1330 } 1331 for (i = 0; i <= CLK_DSIHOST0_SEL_LPLL; i++) { 1332 switch (i) { 1333 case CLK_DSIHOST0_SEL_GPLL: 1334 pll_rate = priv->gpll_hz; 1335 break; 1336 case CLK_DSIHOST0_SEL_CPLL: 1337 pll_rate = priv->cpll_hz; 1338 break; 1339 case CLK_DSIHOST0_SEL_BPLL: 1340 pll_rate = 0; 1341 break; 1342 case CLK_DSIHOST0_SEL_LPLL: 1343 pll_rate = 0; 1344 break; 1345 case CLK_DSIHOST0_SEL_VPLL: 1346 pll_rate = 0; 1347 break; 1348 case CLK_DSIHOST0_SEL_SPLL: 1349 pll_rate = priv->spll_hz; 1350 break; 1351 default: 1352 printf("do not support this vop pll sel\n"); 1353 return -EINVAL; 1354 } 1355 1356 div = DIV_ROUND_UP(pll_rate, rate); 1357 if (div > 255) 1358 continue; 1359 now = pll_rate / div; 1360 if (abs(rate - now) < abs(rate - best_rate)) { 1361 best_rate = now; 1362 best_div = div; 1363 best_sel = i; 1364 } 1365 debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n", 1366 pll_rate, best_rate, best_div, best_sel); 1367 } 1368 if (best_rate) { 1369 rk_clrsetreg(&cru->clksel_con[con], 1370 mask, 1371 best_sel << sel_shift | 1372 (best_div - 1) << div_shift); 1373 } else { 1374 printf("do not support this vop freq %lu\n", rate); 1375 return -EINVAL; 1376 } 1377 return rk3576_clk_csihost_get_clk(priv, clk_id); 1378 } 1379 1380 static ulong rk3576_dclk_ebc_get_clk(struct rk3576_clk_priv *priv, ulong clk_id) 1381 { 1382 struct rk3576_cru *cru = priv->cru; 1383 u32 div, sel, con, parent; 1384 unsigned long m = 0, n = 0; 1385 1386 switch (clk_id) { 1387 case DCLK_EBC: 1388 con = readl(&cru->clksel_con[123]); 1389 div = (con & DCLK_EBC_DIV_MASK) >> DCLK_EBC_DIV_SHIFT; 1390 sel = (con & DCLK_EBC_SEL_MASK) >> DCLK_EBC_SEL_SHIFT; 1391 if (sel == DCLK_EBC_SEL_CPLL) 1392 parent = priv->cpll_hz; 1393 else if (sel == DCLK_EBC_SEL_VPLL) 1394 parent = priv->vpll_hz; 1395 else if (sel == DCLK_EBC_SEL_AUPLL) 1396 parent = priv->aupll_hz; 1397 else if (sel == DCLK_EBC_SEL_LPLL) 1398 parent = priv->lpll_hz / 2; 1399 else if (sel == DCLK_EBC_SEL_GPLL) 1400 parent = priv->gpll_hz; 1401 else if (sel == DCLK_EBC_SEL_FRAC_SRC) 1402 parent = rk3576_dclk_ebc_get_clk(priv, DCLK_EBC_FRAC_SRC); 1403 else 1404 parent = OSC_HZ; 1405 return DIV_TO_RATE(parent, div); 1406 case DCLK_EBC_FRAC_SRC: 1407 con = readl(&cru->clksel_con[123]); 1408 div = readl(&cru->clksel_con[122]); 1409 sel = (con & DCLK_EBC_FRAC_SRC_SEL_MASK) >> DCLK_EBC_FRAC_SRC_SEL_SHIFT; 1410 if (sel == DCLK_EBC_FRAC_SRC_SEL_GPLL) 1411 parent = priv->gpll_hz; 1412 else if (sel == DCLK_EBC_FRAC_SRC_SEL_CPLL) 1413 parent = priv->cpll_hz; 1414 else if (sel == DCLK_EBC_FRAC_SRC_SEL_VPLL) 1415 parent = priv->vpll_hz; 1416 else if (sel == DCLK_EBC_FRAC_SRC_SEL_AUPLL) 1417 parent = priv->aupll_hz; 1418 else 1419 parent = OSC_HZ; 1420 1421 n = div & CLK_UART_FRAC_NUMERATOR_MASK; 1422 n >>= CLK_UART_FRAC_NUMERATOR_SHIFT; 1423 m = div & CLK_UART_FRAC_DENOMINATOR_MASK; 1424 m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT; 1425 return parent * n / m; 1426 default: 1427 return -ENOENT; 1428 } 1429 } 1430 1431 static ulong rk3576_dclk_ebc_set_clk(struct rk3576_clk_priv *priv, 1432 ulong clk_id, ulong rate) 1433 { 1434 struct rk3576_cru *cru = priv->cru; 1435 ulong pll_rate, now, best_rate = 0; 1436 u32 i, con, sel, div, best_div = 0, best_sel = 0; 1437 unsigned long m = 0, n = 0, val; 1438 1439 switch (clk_id) { 1440 case DCLK_EBC: 1441 con = readl(&cru->clksel_con[123]); 1442 sel = (con & DCLK_EBC_SEL_MASK) >> DCLK_EBC_SEL_SHIFT; 1443 if (sel == DCLK_EBC_SEL_VPLL) { 1444 pll_rate = rockchip_pll_get_rate(&rk3576_pll_clks[VPLL], 1445 priv->cru, VPLL); 1446 if (pll_rate >= RK3576_VOP_PLL_LIMIT_FREQ && 1447 pll_rate % rate == 0) { 1448 div = DIV_ROUND_UP(pll_rate, rate); 1449 rk_clrsetreg(&cru->clksel_con[123], 1450 DCLK_EBC_DIV_MASK, 1451 (div - 1) << DCLK_EBC_DIV_SHIFT); 1452 } else { 1453 div = DIV_ROUND_UP(RK3576_VOP_PLL_LIMIT_FREQ, 1454 rate); 1455 if (div % 2) 1456 div = div + 1; 1457 rk_clrsetreg(&cru->clksel_con[123], 1458 DCLK_EBC_DIV_MASK, 1459 (div - 1) << DCLK_EBC_DIV_SHIFT); 1460 rockchip_pll_set_rate(&rk3576_pll_clks[VPLL], 1461 priv->cru, 1462 VPLL, div * rate); 1463 priv->vpll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[VPLL], 1464 priv->cru, 1465 VPLL); 1466 } 1467 } else if (sel == DCLK_EBC_SEL_FRAC_SRC) { 1468 rk3576_dclk_ebc_set_clk(priv, DCLK_EBC_FRAC_SRC, rate); 1469 div = rk3576_dclk_ebc_get_clk(priv, DCLK_EBC_FRAC_SRC) / rate; 1470 rk_clrsetreg(&cru->clksel_con[123], 1471 DCLK_EBC_DIV_MASK, 1472 (div - 1) << DCLK_EBC_DIV_SHIFT); 1473 } else { 1474 for (i = 0; i <= DCLK_EBC_SEL_LPLL; i++) { 1475 switch (i) { 1476 case DCLK_EBC_SEL_GPLL: 1477 pll_rate = priv->gpll_hz; 1478 break; 1479 case DCLK_EBC_SEL_CPLL: 1480 pll_rate = priv->cpll_hz; 1481 break; 1482 case DCLK_EBC_SEL_VPLL: 1483 pll_rate = 0; 1484 break; 1485 case DCLK_EBC_SEL_AUPLL: 1486 pll_rate = priv->aupll_hz; 1487 break; 1488 case DCLK_EBC_SEL_LPLL: 1489 pll_rate = 0; 1490 break; 1491 default: 1492 printf("not support ebc pll sel\n"); 1493 return -EINVAL; 1494 } 1495 1496 div = DIV_ROUND_UP(pll_rate, rate); 1497 if (div > 255) 1498 continue; 1499 now = pll_rate / div; 1500 if (abs(rate - now) < abs(rate - best_rate)) { 1501 best_rate = now; 1502 best_div = div; 1503 best_sel = i; 1504 } 1505 } 1506 1507 if (best_rate) { 1508 rk_clrsetreg(&cru->clksel_con[123], 1509 DCLK_EBC_DIV_MASK | 1510 DCLK_EBC_SEL_MASK, 1511 best_sel << 1512 DCLK_EBC_SEL_SHIFT | 1513 (best_div - 1) << 1514 DCLK_EBC_DIV_SHIFT); 1515 } else { 1516 printf("do not support this vop freq %lu\n", 1517 rate); 1518 return -EINVAL; 1519 } 1520 } 1521 break; 1522 case DCLK_EBC_FRAC_SRC: 1523 sel = DCLK_EBC_FRAC_SRC_SEL_GPLL; 1524 div = 1; 1525 rational_best_approximation(rate, priv->gpll_hz, 1526 GENMASK(16 - 1, 0), 1527 GENMASK(16 - 1, 0), 1528 &m, &n); 1529 1530 if (m < 4 && m != 0) { 1531 if (n % 2 == 0) 1532 val = 1; 1533 else 1534 val = DIV_ROUND_UP(4, m); 1535 1536 n *= val; 1537 m *= val; 1538 if (n > 0xffff) { 1539 n = 0xffff; 1540 } 1541 } 1542 1543 rk_clrsetreg(&cru->clksel_con[123], 1544 DCLK_EBC_FRAC_SRC_SEL_MASK, 1545 (sel << DCLK_EBC_FRAC_SRC_SEL_SHIFT)); 1546 if (m && n) { 1547 val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n; 1548 writel(val, &cru->clksel_con[122]); 1549 } 1550 break; 1551 default: 1552 return -ENOENT; 1553 } 1554 return rk3576_dclk_ebc_get_clk(priv, clk_id); 1555 } 1556 1557 static ulong rk3576_gmac_get_clk(struct rk3576_clk_priv *priv, ulong clk_id) 1558 { 1559 struct rk3576_cru *cru = priv->cru; 1560 u32 con, div, src, p_rate; 1561 1562 switch (clk_id) { 1563 case CLK_GMAC0_PTP_REF_SRC: 1564 case CLK_GMAC0_PTP_REF: 1565 con = readl(&cru->clksel_con[105]); 1566 div = (con & CLK_GMAC0_PTP_DIV_MASK) >> CLK_GMAC0_PTP_DIV_SHIFT; 1567 src = (con & CLK_GMAC0_PTP_SEL_MASK) >> CLK_GMAC0_PTP_SEL_SHIFT; 1568 if (src == CLK_GMAC0_PTP_SEL_GPLL) 1569 p_rate = priv->gpll_hz; 1570 else if (src == CLK_GMAC0_PTP_SEL_CPLL) 1571 p_rate = priv->cpll_hz; 1572 else 1573 p_rate = GMAC0_PTP_REFCLK_IN; 1574 return DIV_TO_RATE(p_rate, div); 1575 case CLK_GMAC1_PTP_REF_SRC: 1576 case CLK_GMAC1_PTP_REF: 1577 con = readl(&cru->clksel_con[104]); 1578 div = (con & CLK_GMAC1_PTP_DIV_MASK) >> CLK_GMAC0_PTP_DIV_SHIFT; 1579 src = (con & CLK_GMAC1_PTP_SEL_MASK) >> CLK_GMAC1_PTP_SEL_SHIFT; 1580 if (src == CLK_GMAC1_PTP_SEL_GPLL) 1581 p_rate = priv->gpll_hz; 1582 else if (src == CLK_GMAC1_PTP_SEL_CPLL) 1583 p_rate = priv->cpll_hz; 1584 else 1585 p_rate = GMAC1_PTP_REFCLK_IN; 1586 return DIV_TO_RATE(p_rate, div); 1587 case CLK_GMAC0_125M_SRC: 1588 con = readl(&cru->clksel_con[30]); 1589 div = (con & CLK_GMAC0_125M_DIV_MASK) >> CLK_GMAC0_125M_DIV_SHIFT; 1590 return DIV_TO_RATE(priv->cpll_hz, div); 1591 case CLK_GMAC1_125M_SRC: 1592 con = readl(&cru->clksel_con[31]); 1593 div = (con & CLK_GMAC1_125M_DIV_MASK) >> CLK_GMAC1_125M_DIV_SHIFT; 1594 return DIV_TO_RATE(priv->cpll_hz, div); 1595 default: 1596 return -ENOENT; 1597 } 1598 } 1599 1600 static ulong rk3576_gmac_set_clk(struct rk3576_clk_priv *priv, 1601 ulong clk_id, ulong rate) 1602 { 1603 struct rk3576_cru *cru = priv->cru; 1604 int div, src; 1605 1606 div = DIV_ROUND_UP(priv->cpll_hz, rate); 1607 1608 switch (clk_id) { 1609 case CLK_GMAC0_PTP_REF_SRC: 1610 case CLK_GMAC0_PTP_REF: 1611 if (rate == GMAC0_PTP_REFCLK_IN) { 1612 src = CLK_GMAC0_PTP_SEL_REFIN; 1613 div = 1; 1614 } else if (!(priv->gpll_hz % rate)) { 1615 src = CLK_GMAC0_PTP_SEL_GPLL; 1616 div = priv->gpll_hz / rate; 1617 } else { 1618 src = CLK_GMAC0_PTP_SEL_CPLL; 1619 div = priv->cpll_hz / rate; 1620 } 1621 rk_clrsetreg(&cru->clksel_con[105], 1622 CLK_GMAC0_PTP_DIV_MASK | CLK_GMAC0_PTP_SEL_MASK, 1623 src << CLK_GMAC0_PTP_SEL_SHIFT | 1624 (div - 1) << CLK_GMAC0_PTP_DIV_SHIFT); 1625 break; 1626 case CLK_GMAC1_PTP_REF_SRC: 1627 case CLK_GMAC1_PTP_REF: 1628 if (rate == GMAC1_PTP_REFCLK_IN) { 1629 src = CLK_GMAC1_PTP_SEL_REFIN; 1630 div = 1; 1631 } else if (!(priv->gpll_hz % rate)) { 1632 src = CLK_GMAC1_PTP_SEL_GPLL; 1633 div = priv->gpll_hz / rate; 1634 } else { 1635 src = CLK_GMAC1_PTP_SEL_CPLL; 1636 div = priv->cpll_hz / rate; 1637 } 1638 rk_clrsetreg(&cru->clksel_con[104], 1639 CLK_GMAC1_PTP_DIV_MASK | CLK_GMAC1_PTP_SEL_MASK, 1640 src << CLK_GMAC1_PTP_SEL_SHIFT | 1641 (div - 1) << CLK_GMAC1_PTP_DIV_SHIFT); 1642 break; 1643 1644 case CLK_GMAC0_125M_SRC: 1645 rk_clrsetreg(&cru->clksel_con[30], 1646 CLK_GMAC0_125M_DIV_MASK, 1647 (div - 1) << CLK_GMAC0_125M_DIV_SHIFT); 1648 break; 1649 case CLK_GMAC1_125M_SRC: 1650 rk_clrsetreg(&cru->clksel_con[31], 1651 CLK_GMAC1_125M_DIV_MASK, 1652 (div - 1) << CLK_GMAC1_125M_DIV_SHIFT); 1653 break; 1654 default: 1655 return -ENOENT; 1656 } 1657 1658 return rk3576_gmac_get_clk(priv, clk_id); 1659 } 1660 1661 static ulong rk3576_uart_frac_get_rate(struct rk3576_clk_priv *priv, ulong clk_id) 1662 { 1663 struct rk3576_cru *cru = priv->cru; 1664 u32 reg, con, fracdiv, p_src, p_rate; 1665 unsigned long m, n; 1666 1667 switch (clk_id) { 1668 case CLK_UART_FRAC_0: 1669 reg = 21; 1670 break; 1671 case CLK_UART_FRAC_1: 1672 reg = 23; 1673 break; 1674 case CLK_UART_FRAC_2: 1675 reg = 25; 1676 break; 1677 default: 1678 return -ENOENT; 1679 } 1680 con = readl(&cru->clksel_con[reg + 1]); 1681 p_src = (con & CLK_UART_SRC_SEL_MASK) >> CLK_UART_SRC_SEL_SHIFT; 1682 if (p_src == CLK_UART_SRC_SEL_GPLL) 1683 p_rate = priv->gpll_hz; 1684 else if (p_src == CLK_UART_SRC_SEL_CPLL) 1685 p_rate = priv->cpll_hz; 1686 else if (p_src == CLK_UART_SRC_SEL_AUPLL) 1687 p_rate = priv->aupll_hz; 1688 else 1689 p_rate = OSC_HZ; 1690 1691 fracdiv = readl(&cru->clksel_con[reg]); 1692 n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK; 1693 n >>= CLK_UART_FRAC_NUMERATOR_SHIFT; 1694 m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK; 1695 m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT; 1696 return p_rate * n / m; 1697 } 1698 1699 static ulong rk3576_uart_frac_set_rate(struct rk3576_clk_priv *priv, 1700 ulong clk_id, ulong rate) 1701 { 1702 struct rk3576_cru *cru = priv->cru; 1703 u32 reg, clk_src, p_rate; 1704 unsigned long m = 0, n = 0, val; 1705 1706 if (priv->cpll_hz % rate == 0) { 1707 clk_src = CLK_UART_SRC_SEL_CPLL; 1708 p_rate = priv->cpll_hz; 1709 } else if (rate == OSC_HZ) { 1710 clk_src = CLK_UART_SRC_SEL_OSC; 1711 p_rate = OSC_HZ; 1712 } else { 1713 clk_src = CLK_UART_SRC_SEL_GPLL; 1714 p_rate = priv->cpll_hz; 1715 } 1716 rational_best_approximation(rate, p_rate, 1717 GENMASK(16 - 1, 0), 1718 GENMASK(16 - 1, 0), 1719 &m, &n); 1720 1721 if (m < 4 && m != 0) { 1722 if (n % 2 == 0) 1723 val = 1; 1724 else 1725 val = DIV_ROUND_UP(4, m); 1726 1727 n *= val; 1728 m *= val; 1729 if (n > 0xffff) { 1730 n = 0xffff; 1731 } 1732 } 1733 1734 1735 switch (clk_id) { 1736 case CLK_UART_FRAC_0: 1737 reg = 21; 1738 break; 1739 case CLK_UART_FRAC_1: 1740 reg = 23; 1741 break; 1742 case CLK_UART_FRAC_2: 1743 reg = 25; 1744 break; 1745 default: 1746 return -ENOENT; 1747 } 1748 rk_clrsetreg(&cru->clksel_con[reg +1], 1749 CLK_UART_SRC_SEL_MASK, 1750 (clk_src << CLK_UART_SRC_SEL_SHIFT)); 1751 if (m && n) { 1752 val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n; 1753 writel(val, &cru->clksel_con[reg]); 1754 } 1755 1756 return rk3576_uart_frac_get_rate(priv, clk_id); 1757 } 1758 1759 1760 static ulong rk3576_uart_get_rate(struct rk3576_clk_priv *priv, ulong clk_id) 1761 { 1762 struct rk3576_cru *cru = priv->cru; 1763 u32 con, div, src, p_rate; 1764 1765 switch (clk_id) { 1766 case SCLK_UART0: 1767 con = readl(&cru->clksel_con[60]); 1768 break; 1769 case SCLK_UART1: 1770 con = readl(&cru->pmuclksel_con[8]); 1771 src = (con & CLK_UART1_SEL_MASK) >> CLK_UART1_SEL_SHIFT; 1772 if (src == CLK_UART1_SEL_OSC) 1773 return OSC_HZ; 1774 con = readl(&cru->clksel_con[27]); 1775 break; 1776 case SCLK_UART2: 1777 con = readl(&cru->clksel_con[61]); 1778 break; 1779 case SCLK_UART3: 1780 con = readl(&cru->clksel_con[62]); 1781 break; 1782 case SCLK_UART4: 1783 con = readl(&cru->clksel_con[63]); 1784 break; 1785 case SCLK_UART5: 1786 con = readl(&cru->clksel_con[64]); 1787 break; 1788 case SCLK_UART6: 1789 con = readl(&cru->clksel_con[65]); 1790 break; 1791 case SCLK_UART7: 1792 con = readl(&cru->clksel_con[66]); 1793 break; 1794 case SCLK_UART8: 1795 con = readl(&cru->clksel_con[67]); 1796 break; 1797 case SCLK_UART9: 1798 con = readl(&cru->clksel_con[68]); 1799 break; 1800 case SCLK_UART10: 1801 con = readl(&cru->clksel_con[69]); 1802 break; 1803 case SCLK_UART11: 1804 con = readl(&cru->clksel_con[70]); 1805 break; 1806 default: 1807 return -ENOENT; 1808 } 1809 if (clk_id == SCLK_UART1) { 1810 src = (con & CLK_UART1_SRC_SEL_SHIFT) >> CLK_UART1_SRC_SEL_SHIFT; 1811 div = (con & CLK_UART1_SRC_DIV_MASK) >> CLK_UART1_SRC_DIV_SHIFT; 1812 } else { 1813 src = (con & CLK_UART_SEL_MASK) >> CLK_UART_SEL_SHIFT; 1814 div = (con & CLK_UART_DIV_MASK) >> CLK_UART_DIV_SHIFT; 1815 } 1816 if (src == CLK_UART_SEL_GPLL) 1817 p_rate = priv->gpll_hz; 1818 else if (src == CLK_UART_SEL_CPLL) 1819 p_rate = priv->cpll_hz; 1820 else if (src == CLK_UART_SEL_AUPLL) 1821 p_rate = priv->aupll_hz; 1822 else if (src == CLK_UART_SEL_FRAC0) 1823 p_rate = rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_0); 1824 else if (src == CLK_UART_SEL_FRAC1) 1825 p_rate = rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_1); 1826 else if (src == CLK_UART_SEL_FRAC2) 1827 p_rate = rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_2); 1828 else 1829 p_rate = OSC_HZ; 1830 1831 return DIV_TO_RATE(p_rate, div); 1832 } 1833 1834 static ulong rk3576_uart_set_rate(struct rk3576_clk_priv *priv, 1835 ulong clk_id, ulong rate) 1836 { 1837 struct rk3576_cru *cru = priv->cru; 1838 u32 reg, clk_src = 0, div = 0; 1839 1840 if (!(priv->gpll_hz % rate)) { 1841 clk_src = CLK_UART_SEL_GPLL; 1842 div = DIV_ROUND_UP(priv->gpll_hz, rate); 1843 } else if (!(priv->cpll_hz % rate)) { 1844 clk_src = CLK_UART_SEL_CPLL; 1845 div = DIV_ROUND_UP(priv->gpll_hz, rate); 1846 } else if (!(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_0) % rate)) { 1847 clk_src = CLK_UART_SEL_FRAC0; 1848 div = DIV_ROUND_UP(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_0), rate); 1849 } else if (!(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_1) % rate)) { 1850 clk_src = CLK_UART_SEL_FRAC1; 1851 div = DIV_ROUND_UP(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_1), rate); 1852 } else if (!(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_2) % rate)) { 1853 clk_src = CLK_UART_SEL_FRAC2; 1854 div = DIV_ROUND_UP(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_2), rate); 1855 } else if (!(OSC_HZ % rate)) { 1856 clk_src = CLK_UART_SEL_OSC; 1857 div = DIV_ROUND_UP(OSC_HZ, rate); 1858 } 1859 1860 switch (clk_id) { 1861 case SCLK_UART0: 1862 reg = 60; 1863 break; 1864 case SCLK_UART1: 1865 if (rate == OSC_HZ) { 1866 rk_clrsetreg(&cru->pmuclksel_con[8], 1867 CLK_UART1_SEL_MASK, 1868 (CLK_UART1_SEL_OSC << CLK_UART1_SEL_SHIFT)); 1869 return 0; 1870 } else { 1871 rk_clrsetreg(&cru->clksel_con[27], 1872 CLK_UART1_SRC_SEL_MASK | 1873 CLK_UART1_SRC_DIV_MASK, 1874 (clk_src << CLK_UART1_SRC_SEL_SHIFT) | 1875 ((div - 1) << CLK_UART1_SRC_DIV_SHIFT)); 1876 rk_clrsetreg(&cru->pmuclksel_con[8], 1877 CLK_UART1_SEL_MASK, 1878 (CLK_UART1_SEL_TOP << CLK_UART1_SEL_SHIFT)); 1879 return 0; 1880 } 1881 break; 1882 case SCLK_UART2: 1883 reg = 61; 1884 break; 1885 case SCLK_UART3: 1886 reg = 62; 1887 break; 1888 case SCLK_UART4: 1889 reg = 63; 1890 break; 1891 case SCLK_UART5: 1892 reg = 64; 1893 break; 1894 case SCLK_UART6: 1895 reg = 65; 1896 break; 1897 case SCLK_UART7: 1898 reg = 66; 1899 break; 1900 case SCLK_UART8: 1901 reg = 67; 1902 break; 1903 case SCLK_UART9: 1904 reg = 68; 1905 break; 1906 case SCLK_UART10: 1907 reg = 69; 1908 break; 1909 case SCLK_UART11: 1910 reg = 70; 1911 break; 1912 default: 1913 return -ENOENT; 1914 } 1915 rk_clrsetreg(&cru->clksel_con[reg], 1916 CLK_UART_SEL_MASK | 1917 CLK_UART_DIV_MASK, 1918 (clk_src << CLK_UART_SEL_SHIFT) | 1919 ((div - 1) << CLK_UART_DIV_SHIFT)); 1920 1921 return rk3576_uart_get_rate(priv, clk_id); 1922 } 1923 1924 static ulong rk3576_ref_clkout_get_clk(struct rk3576_clk_priv *priv, 1925 ulong clk_id) 1926 { 1927 struct rk3576_cru *cru = priv->cru; 1928 u32 reg, con, div, src, p_rate; 1929 1930 switch (clk_id) { 1931 case REF_CLK0_OUT_PLL: 1932 reg = 33; 1933 break; 1934 case REF_CLK1_OUT_PLL: 1935 reg = 34; 1936 break; 1937 case REF_CLK2_OUT_PLL: 1938 reg = 35; 1939 break; 1940 default: 1941 return -ENOENT; 1942 } 1943 con = readl(&cru->clksel_con[reg]); 1944 div = (con & REF_CLK0_OUT_PLL_DIV_MASK) >> REF_CLK0_OUT_PLL_DIV_SHIFT; 1945 src = (con & REF_CLK0_OUT_PLL_SEL_MASK) >> REF_CLK0_OUT_PLL_SEL_SHIFT; 1946 if (src == REF_CLK0_OUT_PLL_SEL_GPLL) 1947 p_rate = priv->gpll_hz; 1948 else if (src == REF_CLK0_OUT_PLL_SEL_CPLL) 1949 p_rate = priv->cpll_hz; 1950 else if (src == REF_CLK0_OUT_PLL_SEL_SPLL) 1951 p_rate = priv->spll_hz; 1952 else if (src == REF_CLK0_OUT_PLL_SEL_AUPLL) 1953 p_rate = priv->aupll_hz; 1954 else if (src == REF_CLK0_OUT_PLL_SEL_LPLL) 1955 p_rate = priv->lpll_hz / 2; 1956 else 1957 p_rate = OSC_HZ; 1958 return DIV_TO_RATE(p_rate, div); 1959 } 1960 1961 static ulong rk3576_ref_clkout_set_clk(struct rk3576_clk_priv *priv, 1962 ulong clk_id, ulong rate) 1963 { 1964 struct rk3576_cru *cru = priv->cru; 1965 ulong p_rate, now, best_rate = 0; 1966 u32 i, con, div, best_div = 0, best_sel = 0; 1967 1968 switch (clk_id) { 1969 case REF_CLK0_OUT_PLL: 1970 con = 33; 1971 break; 1972 case REF_CLK1_OUT_PLL: 1973 con = 34; 1974 break; 1975 case REF_CLK2_OUT_PLL: 1976 con = 35; 1977 break; 1978 default: 1979 return -ENOENT; 1980 } 1981 1982 for (i = 0; i <= REF_CLK0_OUT_PLL_SEL_OSC; i++) { 1983 switch (i) { 1984 case REF_CLK0_OUT_PLL_SEL_GPLL: 1985 p_rate = priv->gpll_hz; 1986 break; 1987 case REF_CLK0_OUT_PLL_SEL_CPLL: 1988 p_rate = priv->cpll_hz; 1989 break; 1990 case REF_CLK0_OUT_PLL_SEL_SPLL: 1991 p_rate = priv->spll_hz; 1992 break; 1993 case REF_CLK0_OUT_PLL_SEL_AUPLL: 1994 p_rate = priv->aupll_hz; 1995 break; 1996 case REF_CLK0_OUT_PLL_SEL_LPLL: 1997 p_rate = 0; 1998 break; 1999 case REF_CLK0_OUT_PLL_SEL_OSC: 2000 p_rate = OSC_HZ; 2001 break; 2002 default: 2003 printf("do not support this vop pll sel\n"); 2004 return -EINVAL; 2005 } 2006 2007 div = DIV_ROUND_UP(p_rate, rate); 2008 if (div > 255) 2009 continue; 2010 now = p_rate / div; 2011 if (abs(rate - now) < abs(rate - best_rate)) { 2012 best_rate = now; 2013 best_div = div; 2014 best_sel = i; 2015 } 2016 debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n", 2017 p_rate, best_rate, best_div, best_sel); 2018 } 2019 if (best_rate) { 2020 rk_clrsetreg(&cru->clksel_con[con], 2021 REF_CLK0_OUT_PLL_DIV_MASK | 2022 REF_CLK0_OUT_PLL_SEL_MASK, 2023 best_sel << REF_CLK0_OUT_PLL_SEL_SHIFT | 2024 (best_div - 1) << REF_CLK0_OUT_PLL_DIV_SHIFT); 2025 } else { 2026 printf("do not support this vop freq %lu\n", rate); 2027 return -EINVAL; 2028 } 2029 2030 return rk3576_ref_clkout_get_clk(priv, clk_id); 2031 } 2032 2033 #endif 2034 2035 static ulong rk3576_ufs_ref_get_rate(struct rk3576_clk_priv *priv, ulong clk_id) 2036 { 2037 struct rk3576_cru *cru = priv->cru; 2038 u32 src, div; 2039 2040 src = readl(&cru->pmuclksel_con[3]) & 0x3; 2041 div= readl(&cru->pmuclksel_con[1]) & 0xff; 2042 if (src == 0) 2043 return OSC_HZ; 2044 else if (src == 2) 2045 return priv->ppll_hz / (div + 1); 2046 else 2047 return 26000000; 2048 2049 } 2050 2051 static ulong rk3576_clk_get_rate(struct clk *clk) 2052 { 2053 struct rk3576_clk_priv *priv = dev_get_priv(clk->dev); 2054 ulong rate = 0; 2055 2056 if (!priv->gpll_hz) { 2057 printf("%s gpll=%lu\n", __func__, priv->gpll_hz); 2058 return -ENOENT; 2059 } 2060 2061 if (!priv->ppll_hz) { 2062 priv->ppll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[PPLL], 2063 priv->cru, PPLL); 2064 } 2065 2066 switch (clk->id) { 2067 case PLL_LPLL: 2068 rate = rockchip_pll_get_rate(&rk3576_pll_clks[LPLL], priv->cru, 2069 LPLL); 2070 priv->lpll_hz = rate; 2071 break; 2072 case PLL_BPLL: 2073 rate = rockchip_pll_get_rate(&rk3576_pll_clks[BPLL], priv->cru, 2074 BPLL); 2075 priv->bpll_hz = rate; 2076 break; 2077 case PLL_GPLL: 2078 rate = rockchip_pll_get_rate(&rk3576_pll_clks[GPLL], priv->cru, 2079 GPLL); 2080 break; 2081 case PLL_CPLL: 2082 rate = rockchip_pll_get_rate(&rk3576_pll_clks[CPLL], priv->cru, 2083 CPLL); 2084 break; 2085 case PLL_VPLL: 2086 rate = rockchip_pll_get_rate(&rk3576_pll_clks[VPLL], priv->cru, 2087 VPLL); 2088 break; 2089 case PLL_AUPLL: 2090 rate = rockchip_pll_get_rate(&rk3576_pll_clks[AUPLL], priv->cru, 2091 AUPLL); 2092 break; 2093 case PLL_PPLL: 2094 rate = rockchip_pll_get_rate(&rk3576_pll_clks[PPLL], priv->cru, 2095 PPLL) * 2; 2096 break; 2097 case ACLK_BUS_ROOT: 2098 case HCLK_BUS_ROOT: 2099 case PCLK_BUS_ROOT: 2100 rate = rk3576_bus_get_clk(priv, clk->id); 2101 break; 2102 case ACLK_TOP: 2103 case HCLK_TOP: 2104 case PCLK_TOP_ROOT: 2105 case ACLK_TOP_MID: 2106 rate = rk3576_top_get_clk(priv, clk->id); 2107 break; 2108 case CLK_I2C0: 2109 case CLK_I2C1: 2110 case CLK_I2C2: 2111 case CLK_I2C3: 2112 case CLK_I2C4: 2113 case CLK_I2C5: 2114 case CLK_I2C6: 2115 case CLK_I2C7: 2116 case CLK_I2C8: 2117 case CLK_I2C9: 2118 rate = rk3576_i2c_get_clk(priv, clk->id); 2119 break; 2120 case CLK_SPI0: 2121 case CLK_SPI1: 2122 case CLK_SPI2: 2123 case CLK_SPI3: 2124 case CLK_SPI4: 2125 rate = rk3576_spi_get_clk(priv, clk->id); 2126 break; 2127 case CLK_PWM1: 2128 case CLK_PWM2: 2129 case CLK_PMU1PWM: 2130 rate = rk3576_pwm_get_clk(priv, clk->id); 2131 break; 2132 case CLK_SARADC: 2133 case CLK_TSADC: 2134 rate = rk3576_adc_get_clk(priv, clk->id); 2135 break; 2136 case CCLK_SRC_SDIO: 2137 case CCLK_SRC_SDMMC0: 2138 case CCLK_SRC_EMMC: 2139 case BCLK_EMMC: 2140 case SCLK_FSPI_X2: 2141 case SCLK_FSPI1_X2: 2142 case DCLK_DECOM: 2143 case HCLK_SDMMC0: 2144 case HCLK_EMMC: 2145 case HCLK_SDIO: 2146 rate = rk3576_mmc_get_clk(priv, clk->id); 2147 break; 2148 case TCLK_WDT0: 2149 rate = OSC_HZ; 2150 break; 2151 #ifndef CONFIG_SPL_BUILD 2152 case ACLK_VOP_ROOT: 2153 case ACLK_VOP: 2154 case ACLK_VO0_ROOT: 2155 case ACLK_VO1_ROOT: 2156 case HCLK_VOP_ROOT: 2157 case PCLK_VOP_ROOT: 2158 rate = rk3576_aclk_vop_get_clk(priv, clk->id); 2159 break; 2160 case DCLK_VP0: 2161 case DCLK_VP0_SRC: 2162 case DCLK_VP1: 2163 case DCLK_VP1_SRC: 2164 case DCLK_VP2: 2165 case DCLK_VP2_SRC: 2166 rate = rk3576_dclk_vop_get_clk(priv, clk->id); 2167 break; 2168 case CLK_GMAC0_PTP_REF_SRC: 2169 case CLK_GMAC1_PTP_REF_SRC: 2170 case CLK_GMAC0_PTP_REF: 2171 case CLK_GMAC1_PTP_REF: 2172 case CLK_GMAC0_125M_SRC: 2173 case CLK_GMAC1_125M_SRC: 2174 rate = rk3576_gmac_get_clk(priv, clk->id); 2175 break; 2176 case CLK_UART_FRAC_0: 2177 case CLK_UART_FRAC_1: 2178 case CLK_UART_FRAC_2: 2179 rate = rk3576_uart_frac_get_rate(priv, clk->id); 2180 break; 2181 case SCLK_UART0: 2182 case SCLK_UART1: 2183 case SCLK_UART2: 2184 case SCLK_UART3: 2185 case SCLK_UART4: 2186 case SCLK_UART5: 2187 case SCLK_UART6: 2188 case SCLK_UART7: 2189 case SCLK_UART8: 2190 case SCLK_UART9: 2191 case SCLK_UART10: 2192 case SCLK_UART11: 2193 rate = rk3576_uart_get_rate(priv, clk->id); 2194 break; 2195 case CLK_DSIHOST0: 2196 rate = rk3576_clk_csihost_get_clk(priv, clk->id); 2197 break; 2198 case DCLK_EBC: 2199 case DCLK_EBC_FRAC_SRC: 2200 rate = rk3576_dclk_ebc_get_clk(priv, clk->id); 2201 break; 2202 case REF_CLK0_OUT_PLL: 2203 case REF_CLK1_OUT_PLL: 2204 case REF_CLK2_OUT_PLL: 2205 rate = rk3576_ref_clkout_get_clk(priv, clk->id); 2206 break; 2207 #endif 2208 case CLK_REF_UFS_CLKOUT: 2209 case CLK_REF_OSC_MPHY: 2210 rate = rk3576_ufs_ref_get_rate(priv, clk->id); 2211 break; 2212 2213 default: 2214 return -ENOENT; 2215 } 2216 2217 return rate; 2218 }; 2219 2220 static ulong rk3576_clk_set_rate(struct clk *clk, ulong rate) 2221 { 2222 struct rk3576_clk_priv *priv = dev_get_priv(clk->dev); 2223 ulong ret = 0; 2224 2225 if (!priv->ppll_hz) { 2226 priv->ppll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[PPLL], 2227 priv->cru, PPLL); 2228 } 2229 if (!priv->aupll_hz) { 2230 priv->aupll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[AUPLL], 2231 priv->cru, AUPLL); 2232 } 2233 2234 switch (clk->id) { 2235 case PLL_CPLL: 2236 ret = rockchip_pll_set_rate(&rk3576_pll_clks[CPLL], priv->cru, 2237 CPLL, rate); 2238 priv->cpll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[CPLL], 2239 priv->cru, CPLL); 2240 break; 2241 case PLL_GPLL: 2242 ret = rockchip_pll_set_rate(&rk3576_pll_clks[GPLL], priv->cru, 2243 GPLL, rate); 2244 priv->gpll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[GPLL], 2245 priv->cru, GPLL); 2246 break; 2247 case PLL_VPLL: 2248 ret = rockchip_pll_set_rate(&rk3576_pll_clks[VPLL], priv->cru, 2249 VPLL, rate); 2250 priv->vpll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[VPLL], 2251 priv->cru, VPLL); 2252 break; 2253 case PLL_AUPLL: 2254 ret = rockchip_pll_set_rate(&rk3576_pll_clks[AUPLL], priv->cru, 2255 AUPLL, rate); 2256 priv->aupll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[AUPLL], 2257 priv->cru, AUPLL); 2258 break; 2259 case PLL_PPLL: 2260 ret = rockchip_pll_set_rate(&rk3576_pll_clks[PPLL], priv->cru, 2261 PPLL, rate); 2262 priv->ppll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[PPLL], 2263 priv->cru, PPLL) * 2; 2264 break; 2265 case ACLK_BUS_ROOT: 2266 case HCLK_BUS_ROOT: 2267 case PCLK_BUS_ROOT: 2268 ret = rk3576_bus_set_clk(priv, clk->id, rate); 2269 break; 2270 case ACLK_TOP: 2271 case HCLK_TOP: 2272 case PCLK_TOP_ROOT: 2273 case ACLK_TOP_MID: 2274 ret = rk3576_top_set_clk(priv, clk->id, rate); 2275 break; 2276 case CLK_I2C0: 2277 case CLK_I2C1: 2278 case CLK_I2C2: 2279 case CLK_I2C3: 2280 case CLK_I2C4: 2281 case CLK_I2C5: 2282 case CLK_I2C6: 2283 case CLK_I2C7: 2284 case CLK_I2C8: 2285 case CLK_I2C9: 2286 ret = rk3576_i2c_set_clk(priv, clk->id, rate); 2287 break; 2288 case CLK_SPI0: 2289 case CLK_SPI1: 2290 case CLK_SPI2: 2291 case CLK_SPI3: 2292 case CLK_SPI4: 2293 ret = rk3576_spi_set_clk(priv, clk->id, rate); 2294 break; 2295 case CLK_PWM1: 2296 case CLK_PWM2: 2297 case CLK_PMU1PWM: 2298 ret = rk3576_pwm_set_clk(priv, clk->id, rate); 2299 break; 2300 case CLK_SARADC: 2301 case CLK_TSADC: 2302 ret = rk3576_adc_set_clk(priv, clk->id, rate); 2303 break; 2304 case CCLK_SRC_SDIO: 2305 case CCLK_SRC_SDMMC0: 2306 case CCLK_SRC_EMMC: 2307 case BCLK_EMMC: 2308 case SCLK_FSPI_X2: 2309 case SCLK_FSPI1_X2: 2310 case DCLK_DECOM: 2311 case HCLK_SDMMC0: 2312 case HCLK_EMMC: 2313 case HCLK_SDIO: 2314 ret = rk3576_mmc_set_clk(priv, clk->id, rate); 2315 break; 2316 case TCLK_WDT0: 2317 ret = OSC_HZ; 2318 break; 2319 #ifndef CONFIG_SPL_BUILD 2320 case ACLK_VOP_ROOT: 2321 case ACLK_VOP: 2322 case ACLK_VO0_ROOT: 2323 case ACLK_VO1_ROOT: 2324 case HCLK_VOP_ROOT: 2325 case PCLK_VOP_ROOT: 2326 ret = rk3576_aclk_vop_set_clk(priv, clk->id, rate); 2327 break; 2328 case DCLK_VP0: 2329 case DCLK_VP0_SRC: 2330 case DCLK_VP1: 2331 case DCLK_VP1_SRC: 2332 case DCLK_VP2: 2333 case DCLK_VP2_SRC: 2334 ret = rk3576_dclk_vop_set_clk(priv, clk->id, rate); 2335 break; 2336 case CLK_GMAC0_PTP_REF_SRC: 2337 case CLK_GMAC1_PTP_REF_SRC: 2338 case CLK_GMAC0_PTP_REF: 2339 case CLK_GMAC1_PTP_REF: 2340 case CLK_GMAC0_125M_SRC: 2341 case CLK_GMAC1_125M_SRC: 2342 ret = rk3576_gmac_set_clk(priv, clk->id, rate); 2343 break; 2344 case CLK_UART_FRAC_0: 2345 case CLK_UART_FRAC_1: 2346 case CLK_UART_FRAC_2: 2347 ret = rk3576_uart_frac_set_rate(priv, clk->id, rate); 2348 break; 2349 case SCLK_UART0: 2350 case SCLK_UART1: 2351 case SCLK_UART2: 2352 case SCLK_UART3: 2353 case SCLK_UART4: 2354 case SCLK_UART5: 2355 case SCLK_UART6: 2356 case SCLK_UART7: 2357 case SCLK_UART8: 2358 case SCLK_UART9: 2359 case SCLK_UART10: 2360 case SCLK_UART11: 2361 ret = rk3576_uart_set_rate(priv, clk->id, rate); 2362 break; 2363 case CLK_DSIHOST0: 2364 ret = rk3576_clk_csihost_set_clk(priv, clk->id, rate); 2365 break; 2366 case DCLK_EBC: 2367 case DCLK_EBC_FRAC_SRC: 2368 ret = rk3576_dclk_ebc_set_clk(priv, clk->id, rate); 2369 break; 2370 case REF_CLK0_OUT_PLL: 2371 case REF_CLK1_OUT_PLL: 2372 case REF_CLK2_OUT_PLL: 2373 ret = rk3576_ref_clkout_set_clk(priv, clk->id, rate); 2374 break; 2375 #endif 2376 default: 2377 return -ENOENT; 2378 } 2379 2380 return ret; 2381 }; 2382 2383 #if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA)) 2384 static int __maybe_unused rk3576_dclk_vop_set_parent(struct clk *clk, 2385 struct clk *parent) 2386 { 2387 struct rk3576_clk_priv *priv = dev_get_priv(clk->dev); 2388 struct rk3576_cru *cru = priv->cru; 2389 u32 sel; 2390 const char *clock_dev_name = parent->dev->name; 2391 2392 if (parent->id == PLL_VPLL) 2393 sel = 2; 2394 else if (parent->id == PLL_GPLL) 2395 sel = 0; 2396 else if (parent->id == PLL_CPLL) 2397 sel = 1; 2398 else if (parent->id == PLL_BPLL) 2399 sel = 3; 2400 else 2401 sel = 4; 2402 2403 switch (clk->id) { 2404 case DCLK_VP0_SRC: 2405 rk_clrsetreg(&cru->clksel_con[145], DCLK0_VOP_SRC_SEL_MASK, 2406 sel << DCLK0_VOP_SRC_SEL_SHIFT); 2407 break; 2408 case DCLK_VP1_SRC: 2409 rk_clrsetreg(&cru->clksel_con[146], DCLK0_VOP_SRC_SEL_MASK, 2410 sel << DCLK0_VOP_SRC_SEL_SHIFT); 2411 break; 2412 case DCLK_VP2_SRC: 2413 rk_clrsetreg(&cru->clksel_con[147], DCLK0_VOP_SRC_SEL_MASK, 2414 sel << DCLK0_VOP_SRC_SEL_SHIFT); 2415 break; 2416 case DCLK_VP0: 2417 if (!strcmp(clock_dev_name, "hdmiphypll_clk0")) 2418 sel = 1; 2419 else 2420 sel = 0; 2421 rk_clrsetreg(&cru->clksel_con[147], DCLK0_VOP_SEL_MASK, 2422 sel << DCLK0_VOP_SEL_SHIFT); 2423 break; 2424 case DCLK_VP1: 2425 if (!strcmp(clock_dev_name, "hdmiphypll_clk0")) 2426 sel = 1; 2427 else 2428 sel = 0; 2429 rk_clrsetreg(&cru->clksel_con[147], DCLK1_VOP_SEL_MASK, 2430 sel << DCLK1_VOP_SEL_SHIFT); 2431 break; 2432 case DCLK_VP2: 2433 if (!strcmp(clock_dev_name, "hdmiphypll_clk0")) 2434 sel = 1; 2435 else 2436 sel = 0; 2437 rk_clrsetreg(&cru->clksel_con[147], DCLK2_VOP_SEL_MASK, 2438 sel << DCLK2_VOP_SEL_SHIFT); 2439 break; 2440 case DCLK_EBC: 2441 if (parent->id == PLL_GPLL) 2442 sel = 0; 2443 else if (parent->id == PLL_CPLL) 2444 sel = 1; 2445 else if (parent->id == PLL_VPLL) 2446 sel = 2; 2447 else if (parent->id == PLL_AUPLL) 2448 sel = 3; 2449 else if (parent->id == PLL_LPLL) 2450 sel = 4; 2451 else if (parent->id == DCLK_EBC_FRAC_SRC) 2452 sel = 5; 2453 else 2454 sel = 6; 2455 rk_clrsetreg(&cru->clksel_con[123], DCLK_EBC_SEL_MASK, 2456 sel << DCLK_EBC_SEL_SHIFT); 2457 break; 2458 default: 2459 return -EINVAL; 2460 } 2461 return 0; 2462 } 2463 2464 static int __maybe_unused rk3576_ufs_ref_set_parent(struct clk *clk, 2465 struct clk *parent) 2466 { 2467 struct rk3576_clk_priv *priv = dev_get_priv(clk->dev); 2468 struct rk3576_cru *cru = priv->cru; 2469 u32 sel; 2470 const char *clock_dev_name = parent->dev->name; 2471 2472 if (parent->id == CLK_REF_MPHY_26M) 2473 sel = 2; 2474 else if (!strcmp(clock_dev_name, "xin24m")) 2475 sel = 0; 2476 else 2477 sel = 1; 2478 2479 rk_clrsetreg(&cru->pmuclksel_con[3], 0x3, sel << 0); 2480 return 0; 2481 } 2482 2483 static int rk3576_clk_set_parent(struct clk *clk, struct clk *parent) 2484 { 2485 switch (clk->id) { 2486 case DCLK_VP0_SRC: 2487 case DCLK_VP1_SRC: 2488 case DCLK_VP2_SRC: 2489 case DCLK_VP0: 2490 case DCLK_VP1: 2491 case DCLK_VP2: 2492 case DCLK_EBC: 2493 return rk3576_dclk_vop_set_parent(clk, parent); 2494 case CLK_REF_OSC_MPHY: 2495 return rk3576_ufs_ref_set_parent(clk, parent); 2496 2497 default: 2498 return -ENOENT; 2499 } 2500 2501 return 0; 2502 } 2503 #endif 2504 2505 static struct clk_ops rk3576_clk_ops = { 2506 .get_rate = rk3576_clk_get_rate, 2507 .set_rate = rk3576_clk_set_rate, 2508 #if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA)) 2509 .set_parent = rk3576_clk_set_parent, 2510 #endif 2511 }; 2512 2513 static void rk3576_clk_init(struct rk3576_clk_priv *priv) 2514 { 2515 int ret; 2516 2517 priv->spll_hz = 702000000; 2518 2519 if (priv->cpll_hz != CPLL_HZ) { 2520 ret = rockchip_pll_set_rate(&rk3576_pll_clks[CPLL], priv->cru, 2521 CPLL, CPLL_HZ); 2522 if (!ret) 2523 priv->cpll_hz = CPLL_HZ; 2524 } 2525 if (priv->gpll_hz != GPLL_HZ) { 2526 ret = rockchip_pll_set_rate(&rk3576_pll_clks[GPLL], priv->cru, 2527 GPLL, GPLL_HZ); 2528 if (!ret) 2529 priv->gpll_hz = GPLL_HZ; 2530 } 2531 rk_clrsetreg(&priv->cru->clksel_con[123], 2532 DCLK_EBC_FRAC_SRC_SEL_MASK, 2533 (DCLK_EBC_FRAC_SRC_SEL_GPLL << 2534 DCLK_EBC_FRAC_SRC_SEL_SHIFT)); 2535 } 2536 2537 static int rk3576_clk_probe(struct udevice *dev) 2538 { 2539 struct rk3576_clk_priv *priv = dev_get_priv(dev); 2540 int ret; 2541 #if CONFIG_IS_ENABLED(CLK_SCMI) 2542 struct clk clk; 2543 #endif 2544 2545 priv->sync_kernel = false; 2546 2547 #ifdef CONFIG_SPL_BUILD 2548 /* relase presetn_bigcore_biu/cru/grf */ 2549 writel(0x1c001c00, 0x26010010); 2550 /* set spll to normal mode */ 2551 writel(BITS_WITH_WMASK(2, 0x7U, 6), 2552 RK3576_SCRU_BASE + RK3576_PLL_CON(137)); 2553 writel(BITS_WITH_WMASK(1, 0x3U, 0), 2554 RK3576_SCRU_BASE + RK3576_MODE_CON0); 2555 /* fix ppll\aupll\cpll */ 2556 writel(BITS_WITH_WMASK(2, 0x7U, 6), 2557 RK3576_CRU_BASE + RK3576_PMU_PLL_CON(129)); 2558 writel(BITS_WITH_WMASK(2, 0x7U, 6), 2559 RK3576_CRU_BASE + RK3576_PLL_CON(97)); 2560 writel(BITS_WITH_WMASK(2, 0x7U, 6), 2561 RK3576_CRU_BASE + RK3576_PLL_CON(105)); 2562 writel(BITS_WITH_WMASK(1, 0x3U, 6), 2563 RK3576_CRU_BASE + RK3576_MODE_CON0); 2564 writel(BITS_WITH_WMASK(1, 0x3U, 8), 2565 RK3576_CRU_BASE + RK3576_MODE_CON0); 2566 /* init cci */ 2567 writel(0xffff0000, RK3576_CRU_BASE + RK3576_CCI_CLKSEL_CON(4)); 2568 rockchip_pll_set_rate(&rk3576_pll_clks[BPLL], priv->cru, 2569 BPLL, LPLL_HZ); 2570 if (!priv->armclk_enter_hz) { 2571 ret = rockchip_pll_set_rate(&rk3576_pll_clks[LPLL], priv->cru, 2572 LPLL, LPLL_HZ); 2573 priv->armclk_enter_hz = 2574 rockchip_pll_get_rate(&rk3576_pll_clks[LPLL], 2575 priv->cru, LPLL); 2576 priv->armclk_init_hz = priv->armclk_enter_hz; 2577 rk_clrsetreg(&priv->cru->litclksel_con[0], CLK_LITCORE_DIV_MASK, 2578 0 << CLK_LITCORE_DIV_SHIFT); 2579 } 2580 /* init cci */ 2581 writel(0xffff20cb, RK3576_CRU_BASE + RK3576_CCI_CLKSEL_CON(4)); 2582 2583 /* Change bigcore rm from 4 to 3 */ 2584 writel(0x001c000c, RK3576_BIGCORE_GRF_BASE + 0x3c); 2585 writel(0x001c000c, RK3576_BIGCORE_GRF_BASE + 0x44); 2586 writel(0x00020002, RK3576_BIGCORE_GRF_BASE + 0x38); 2587 udelay(1); 2588 writel(0x00020000, RK3576_BIGCORE_GRF_BASE + 0x38); 2589 /* Change litcore rm from 4 to 3 */ 2590 writel(0x001c000c, RK3576_LITCORE_GRF_BASE + 0x3c); 2591 writel(0x001c000c, RK3576_LITCORE_GRF_BASE + 0x44); 2592 writel(0x00020002, RK3576_LITCORE_GRF_BASE + 0x38); 2593 udelay(1); 2594 writel(0x00020000, RK3576_LITCORE_GRF_BASE + 0x38); 2595 /* Change cci rm form 4 to 3 */ 2596 writel(0x001c000c, RK3576_CCI_GRF_BASE + 0x54); 2597 #endif 2598 2599 priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 2600 if (IS_ERR(priv->grf)) 2601 return PTR_ERR(priv->grf); 2602 2603 rk3576_clk_init(priv); 2604 2605 #if CONFIG_IS_ENABLED(CLK_SCMI) 2606 #ifndef CONFIG_SPL_BUILD 2607 ret = rockchip_get_scmi_clk(&clk.dev); 2608 if (ret) { 2609 printf("Failed to get scmi clk dev, ret=%d\n", ret); 2610 return ret; 2611 } 2612 if (!priv->armclk_enter_hz) { 2613 clk.id = ARMCLK_L; 2614 ret = clk_set_rate(&clk, CPU_PVTPLL_HZ); 2615 if (ret < 0) { 2616 printf("Failed to set cpubl, ret=%d\n", ret); 2617 } else { 2618 priv->armclk_enter_hz = CPU_PVTPLL_HZ; 2619 priv->armclk_init_hz = CPU_PVTPLL_HZ; 2620 } 2621 } 2622 clk.id = ARMCLK_B; 2623 ret = clk_set_rate(&clk, CPU_PVTPLL_HZ); 2624 if (ret < 0) 2625 printf("Failed to set cpub, ret=%d\n", ret); 2626 #endif 2627 #endif 2628 2629 /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */ 2630 ret = clk_set_defaults(dev); 2631 if (ret) 2632 debug("%s clk_set_defaults failed %d\n", __func__, ret); 2633 else 2634 priv->sync_kernel = true; 2635 2636 return 0; 2637 } 2638 2639 static int rk3576_clk_ofdata_to_platdata(struct udevice *dev) 2640 { 2641 struct rk3576_clk_priv *priv = dev_get_priv(dev); 2642 2643 priv->cru = dev_read_addr_ptr(dev); 2644 2645 return 0; 2646 } 2647 2648 static int rk3576_clk_bind(struct udevice *dev) 2649 { 2650 int ret; 2651 struct udevice *sys_child, *sf_child; 2652 struct sysreset_reg *priv; 2653 struct softreset_reg *sf_priv; 2654 2655 /* The reset driver does not have a device node, so bind it here */ 2656 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset", 2657 &sys_child); 2658 if (ret) { 2659 debug("Warning: No sysreset driver: ret=%d\n", ret); 2660 } else { 2661 priv = malloc(sizeof(struct sysreset_reg)); 2662 priv->glb_srst_fst_value = offsetof(struct rk3576_cru, 2663 glb_srst_fst); 2664 priv->glb_srst_snd_value = offsetof(struct rk3576_cru, 2665 glb_srsr_snd); 2666 sys_child->priv = priv; 2667 } 2668 2669 ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset", 2670 dev_ofnode(dev), &sf_child); 2671 if (ret) { 2672 debug("Warning: No rockchip reset driver: ret=%d\n", ret); 2673 } else { 2674 sf_priv = malloc(sizeof(struct softreset_reg)); 2675 sf_priv->sf_reset_offset = offsetof(struct rk3576_cru, 2676 softrst_con[0]); 2677 sf_priv->sf_reset_num = 524454; 2678 sf_child->priv = sf_priv; 2679 } 2680 2681 return 0; 2682 } 2683 2684 static const struct udevice_id rk3576_clk_ids[] = { 2685 { .compatible = "rockchip,rk3576-cru" }, 2686 { } 2687 }; 2688 2689 U_BOOT_DRIVER(rockchip_rk3576_cru) = { 2690 .name = "rockchip_rk3576_cru", 2691 .id = UCLASS_CLK, 2692 .of_match = rk3576_clk_ids, 2693 .priv_auto_alloc_size = sizeof(struct rk3576_clk_priv), 2694 .ofdata_to_platdata = rk3576_clk_ofdata_to_platdata, 2695 .ops = &rk3576_clk_ops, 2696 .bind = rk3576_clk_bind, 2697 .probe = rk3576_clk_probe, 2698 }; 2699 2700 #ifndef CONFIG_SPL_BUILD 2701 /** 2702 * soc_clk_dump() - Print clock frequencies 2703 * Returns zero on success 2704 * 2705 * Implementation for the clk dump command. 2706 */ 2707 int soc_clk_dump(void) 2708 { 2709 struct udevice *cru_dev; 2710 struct rk3576_clk_priv *priv; 2711 const struct rk3576_clk_info *clk_dump; 2712 struct clk clk; 2713 unsigned long clk_count = ARRAY_SIZE(clks_dump); 2714 unsigned long rate; 2715 int i, ret; 2716 2717 ret = uclass_get_device_by_driver(UCLASS_CLK, 2718 DM_GET_DRIVER(rockchip_rk3576_cru), 2719 &cru_dev); 2720 if (ret) { 2721 printf("%s failed to get cru device\n", __func__); 2722 return ret; 2723 } 2724 2725 priv = dev_get_priv(cru_dev); 2726 printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n", 2727 priv->sync_kernel ? "sync kernel" : "uboot", 2728 priv->armclk_enter_hz / 1000, 2729 priv->armclk_init_hz / 1000, 2730 priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0, 2731 priv->set_armclk_rate ? " KHz" : "N/A"); 2732 for (i = 0; i < clk_count; i++) { 2733 clk_dump = &clks_dump[i]; 2734 if (clk_dump->name) { 2735 memset(&clk, 0, sizeof(struct clk)); 2736 clk.id = clk_dump->id; 2737 if (clk_dump->is_cru) 2738 ret = clk_request(cru_dev, &clk); 2739 if (ret < 0) 2740 return ret; 2741 2742 rate = clk_get_rate(&clk); 2743 clk_free(&clk); 2744 if (rate < 0) 2745 printf(" %s %s\n", clk_dump->name, 2746 "unknown"); 2747 else 2748 printf(" %s %lu KHz\n", clk_dump->name, 2749 rate / 1000); 2750 } 2751 } 2752 2753 return 0; 2754 } 2755 #endif 2756