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