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 u32 div, sel; 1436 unsigned long m = 0, n = 0, val; 1437 1438 switch (clk_id) { 1439 case DCLK_EBC: 1440 if (!(priv->gpll_hz % rate)) { 1441 sel = DCLK_EBC_SEL_GPLL; 1442 div = priv->gpll_hz / rate; 1443 } else if (!(priv->cpll_hz % rate)) { 1444 sel = DCLK_EBC_SEL_CPLL; 1445 div = priv->cpll_hz / rate; 1446 } else if (!(priv->aupll_hz % rate)) { 1447 sel = DCLK_EBC_SEL_AUPLL; 1448 div = priv->aupll_hz / rate; 1449 } else if (!(priv->vpll_hz % rate)) { 1450 sel = DCLK_EBC_SEL_VPLL; 1451 div = priv->vpll_hz / rate; 1452 } else if (!(OSC_HZ % rate)) { 1453 sel = DCLK_EBC_SEL_OSC; 1454 div = OSC_HZ / rate; 1455 } else { 1456 sel = DCLK_EBC_SEL_FRAC_SRC; 1457 rk3576_dclk_ebc_set_clk(priv, DCLK_EBC_FRAC_SRC, rate); 1458 div = rk3576_dclk_ebc_get_clk(priv, DCLK_EBC_FRAC_SRC) / rate; 1459 } 1460 rk_clrsetreg(&cru->clksel_con[123], 1461 DCLK_EBC_SEL_MASK | DCLK_EBC_DIV_MASK, 1462 (sel << DCLK_EBC_SEL_SHIFT) | 1463 (div - 1) << DCLK_EBC_DIV_SHIFT); 1464 break; 1465 case DCLK_EBC_FRAC_SRC: 1466 sel = DCLK_EBC_FRAC_SRC_SEL_GPLL; 1467 div = 1; 1468 rational_best_approximation(rate, priv->gpll_hz, 1469 GENMASK(16 - 1, 0), 1470 GENMASK(16 - 1, 0), 1471 &m, &n); 1472 1473 if (m < 4 && m != 0) { 1474 if (n % 2 == 0) 1475 val = 1; 1476 else 1477 val = DIV_ROUND_UP(4, m); 1478 1479 n *= val; 1480 m *= val; 1481 if (n > 0xffff) { 1482 n = 0xffff; 1483 } 1484 } 1485 1486 rk_clrsetreg(&cru->clksel_con[123], 1487 DCLK_EBC_FRAC_SRC_SEL_MASK, 1488 (sel << DCLK_EBC_FRAC_SRC_SEL_SHIFT)); 1489 if (m && n) { 1490 val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n; 1491 writel(val, &cru->clksel_con[122]); 1492 } 1493 break; 1494 default: 1495 return -ENOENT; 1496 } 1497 return rk3576_dclk_ebc_get_clk(priv, clk_id); 1498 } 1499 1500 static ulong rk3576_gmac_get_clk(struct rk3576_clk_priv *priv, ulong clk_id) 1501 { 1502 struct rk3576_cru *cru = priv->cru; 1503 u32 con, div, src, p_rate; 1504 1505 switch (clk_id) { 1506 case CLK_GMAC0_PTP_REF_SRC: 1507 case CLK_GMAC0_PTP_REF: 1508 con = readl(&cru->clksel_con[105]); 1509 div = (con & CLK_GMAC0_PTP_DIV_MASK) >> CLK_GMAC0_PTP_DIV_SHIFT; 1510 src = (con & CLK_GMAC0_PTP_SEL_MASK) >> CLK_GMAC0_PTP_SEL_SHIFT; 1511 if (src == CLK_GMAC0_PTP_SEL_GPLL) 1512 p_rate = priv->gpll_hz; 1513 else if (src == CLK_GMAC0_PTP_SEL_CPLL) 1514 p_rate = priv->cpll_hz; 1515 else 1516 p_rate = GMAC0_PTP_REFCLK_IN; 1517 return DIV_TO_RATE(p_rate, div); 1518 case CLK_GMAC1_PTP_REF_SRC: 1519 case CLK_GMAC1_PTP_REF: 1520 con = readl(&cru->clksel_con[104]); 1521 div = (con & CLK_GMAC1_PTP_DIV_MASK) >> CLK_GMAC0_PTP_DIV_SHIFT; 1522 src = (con & CLK_GMAC1_PTP_SEL_MASK) >> CLK_GMAC1_PTP_SEL_SHIFT; 1523 if (src == CLK_GMAC1_PTP_SEL_GPLL) 1524 p_rate = priv->gpll_hz; 1525 else if (src == CLK_GMAC1_PTP_SEL_CPLL) 1526 p_rate = priv->cpll_hz; 1527 else 1528 p_rate = GMAC1_PTP_REFCLK_IN; 1529 return DIV_TO_RATE(p_rate, div); 1530 case CLK_GMAC0_125M_SRC: 1531 con = readl(&cru->clksel_con[30]); 1532 div = (con & CLK_GMAC0_125M_DIV_MASK) >> CLK_GMAC0_125M_DIV_SHIFT; 1533 return DIV_TO_RATE(priv->cpll_hz, div); 1534 case CLK_GMAC1_125M_SRC: 1535 con = readl(&cru->clksel_con[31]); 1536 div = (con & CLK_GMAC1_125M_DIV_MASK) >> CLK_GMAC1_125M_DIV_SHIFT; 1537 return DIV_TO_RATE(priv->cpll_hz, div); 1538 default: 1539 return -ENOENT; 1540 } 1541 } 1542 1543 static ulong rk3576_gmac_set_clk(struct rk3576_clk_priv *priv, 1544 ulong clk_id, ulong rate) 1545 { 1546 struct rk3576_cru *cru = priv->cru; 1547 int div, src; 1548 1549 div = DIV_ROUND_UP(priv->cpll_hz, rate); 1550 1551 switch (clk_id) { 1552 case CLK_GMAC0_PTP_REF_SRC: 1553 case CLK_GMAC0_PTP_REF: 1554 if (rate == GMAC0_PTP_REFCLK_IN) { 1555 src = CLK_GMAC0_PTP_SEL_REFIN; 1556 div = 1; 1557 } else if (!(priv->gpll_hz % rate)) { 1558 src = CLK_GMAC0_PTP_SEL_GPLL; 1559 div = priv->gpll_hz / rate; 1560 } else { 1561 src = CLK_GMAC0_PTP_SEL_CPLL; 1562 div = priv->cpll_hz / rate; 1563 } 1564 rk_clrsetreg(&cru->clksel_con[105], 1565 CLK_GMAC0_PTP_DIV_MASK | CLK_GMAC0_PTP_SEL_MASK, 1566 src << CLK_GMAC0_PTP_SEL_SHIFT | 1567 (div - 1) << CLK_GMAC0_PTP_DIV_SHIFT); 1568 break; 1569 case CLK_GMAC1_PTP_REF_SRC: 1570 case CLK_GMAC1_PTP_REF: 1571 if (rate == GMAC1_PTP_REFCLK_IN) { 1572 src = CLK_GMAC1_PTP_SEL_REFIN; 1573 div = 1; 1574 } else if (!(priv->gpll_hz % rate)) { 1575 src = CLK_GMAC1_PTP_SEL_GPLL; 1576 div = priv->gpll_hz / rate; 1577 } else { 1578 src = CLK_GMAC1_PTP_SEL_CPLL; 1579 div = priv->cpll_hz / rate; 1580 } 1581 rk_clrsetreg(&cru->clksel_con[104], 1582 CLK_GMAC1_PTP_DIV_MASK | CLK_GMAC1_PTP_SEL_MASK, 1583 src << CLK_GMAC1_PTP_SEL_SHIFT | 1584 (div - 1) << CLK_GMAC1_PTP_DIV_SHIFT); 1585 break; 1586 1587 case CLK_GMAC0_125M_SRC: 1588 rk_clrsetreg(&cru->clksel_con[30], 1589 CLK_GMAC0_125M_DIV_MASK, 1590 (div - 1) << CLK_GMAC0_125M_DIV_SHIFT); 1591 break; 1592 case CLK_GMAC1_125M_SRC: 1593 rk_clrsetreg(&cru->clksel_con[31], 1594 CLK_GMAC1_125M_DIV_MASK, 1595 (div - 1) << CLK_GMAC1_125M_DIV_SHIFT); 1596 break; 1597 default: 1598 return -ENOENT; 1599 } 1600 1601 return rk3576_gmac_get_clk(priv, clk_id); 1602 } 1603 1604 static ulong rk3576_uart_frac_get_rate(struct rk3576_clk_priv *priv, ulong clk_id) 1605 { 1606 struct rk3576_cru *cru = priv->cru; 1607 u32 reg, con, fracdiv, p_src, p_rate; 1608 unsigned long m, n; 1609 1610 switch (clk_id) { 1611 case CLK_UART_FRAC_0: 1612 reg = 21; 1613 break; 1614 case CLK_UART_FRAC_1: 1615 reg = 23; 1616 break; 1617 case CLK_UART_FRAC_2: 1618 reg = 25; 1619 break; 1620 default: 1621 return -ENOENT; 1622 } 1623 con = readl(&cru->clksel_con[reg + 1]); 1624 p_src = (con & CLK_UART_SRC_SEL_MASK) >> CLK_UART_SRC_SEL_SHIFT; 1625 if (p_src == CLK_UART_SRC_SEL_GPLL) 1626 p_rate = priv->gpll_hz; 1627 else if (p_src == CLK_UART_SRC_SEL_CPLL) 1628 p_rate = priv->cpll_hz; 1629 else if (p_src == CLK_UART_SRC_SEL_AUPLL) 1630 p_rate = priv->aupll_hz; 1631 else 1632 p_rate = OSC_HZ; 1633 1634 fracdiv = readl(&cru->clksel_con[reg]); 1635 n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK; 1636 n >>= CLK_UART_FRAC_NUMERATOR_SHIFT; 1637 m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK; 1638 m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT; 1639 return p_rate * n / m; 1640 } 1641 1642 static ulong rk3576_uart_frac_set_rate(struct rk3576_clk_priv *priv, 1643 ulong clk_id, ulong rate) 1644 { 1645 struct rk3576_cru *cru = priv->cru; 1646 u32 reg, clk_src, p_rate; 1647 unsigned long m = 0, n = 0, val; 1648 1649 if (priv->cpll_hz % rate == 0) { 1650 clk_src = CLK_UART_SRC_SEL_CPLL; 1651 p_rate = priv->cpll_hz; 1652 } else if (rate == OSC_HZ) { 1653 clk_src = CLK_UART_SRC_SEL_OSC; 1654 p_rate = OSC_HZ; 1655 } else { 1656 clk_src = CLK_UART_SRC_SEL_GPLL; 1657 p_rate = priv->cpll_hz; 1658 } 1659 rational_best_approximation(rate, p_rate, 1660 GENMASK(16 - 1, 0), 1661 GENMASK(16 - 1, 0), 1662 &m, &n); 1663 1664 if (m < 4 && m != 0) { 1665 if (n % 2 == 0) 1666 val = 1; 1667 else 1668 val = DIV_ROUND_UP(4, m); 1669 1670 n *= val; 1671 m *= val; 1672 if (n > 0xffff) { 1673 n = 0xffff; 1674 } 1675 } 1676 1677 1678 switch (clk_id) { 1679 case CLK_UART_FRAC_0: 1680 reg = 21; 1681 break; 1682 case CLK_UART_FRAC_1: 1683 reg = 23; 1684 break; 1685 case CLK_UART_FRAC_2: 1686 reg = 25; 1687 break; 1688 default: 1689 return -ENOENT; 1690 } 1691 rk_clrsetreg(&cru->clksel_con[reg +1], 1692 CLK_UART_SRC_SEL_MASK, 1693 (clk_src << CLK_UART_SRC_SEL_SHIFT)); 1694 if (m && n) { 1695 val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n; 1696 writel(val, &cru->clksel_con[reg]); 1697 } 1698 1699 return rk3576_uart_frac_get_rate(priv, clk_id); 1700 } 1701 1702 1703 static ulong rk3576_uart_get_rate(struct rk3576_clk_priv *priv, ulong clk_id) 1704 { 1705 struct rk3576_cru *cru = priv->cru; 1706 u32 con, div, src, p_rate; 1707 1708 switch (clk_id) { 1709 case SCLK_UART0: 1710 con = readl(&cru->clksel_con[60]); 1711 break; 1712 case SCLK_UART1: 1713 con = readl(&cru->pmuclksel_con[8]); 1714 src = (con & CLK_UART1_SEL_MASK) >> CLK_UART1_SEL_SHIFT; 1715 if (src == CLK_UART1_SEL_OSC) 1716 return OSC_HZ; 1717 con = readl(&cru->clksel_con[27]); 1718 break; 1719 case SCLK_UART2: 1720 con = readl(&cru->clksel_con[61]); 1721 break; 1722 case SCLK_UART3: 1723 con = readl(&cru->clksel_con[62]); 1724 break; 1725 case SCLK_UART4: 1726 con = readl(&cru->clksel_con[63]); 1727 break; 1728 case SCLK_UART5: 1729 con = readl(&cru->clksel_con[64]); 1730 break; 1731 case SCLK_UART6: 1732 con = readl(&cru->clksel_con[65]); 1733 break; 1734 case SCLK_UART7: 1735 con = readl(&cru->clksel_con[66]); 1736 break; 1737 case SCLK_UART8: 1738 con = readl(&cru->clksel_con[67]); 1739 break; 1740 case SCLK_UART9: 1741 con = readl(&cru->clksel_con[68]); 1742 break; 1743 case SCLK_UART10: 1744 con = readl(&cru->clksel_con[69]); 1745 break; 1746 case SCLK_UART11: 1747 con = readl(&cru->clksel_con[70]); 1748 break; 1749 default: 1750 return -ENOENT; 1751 } 1752 if (clk_id == SCLK_UART1) { 1753 src = (con & CLK_UART1_SRC_SEL_SHIFT) >> CLK_UART1_SRC_SEL_SHIFT; 1754 div = (con & CLK_UART1_SRC_DIV_MASK) >> CLK_UART1_SRC_DIV_SHIFT; 1755 } else { 1756 src = (con & CLK_UART_SEL_MASK) >> CLK_UART_SEL_SHIFT; 1757 div = (con & CLK_UART_DIV_MASK) >> CLK_UART_DIV_SHIFT; 1758 } 1759 if (src == CLK_UART_SEL_GPLL) 1760 p_rate = priv->gpll_hz; 1761 else if (src == CLK_UART_SEL_CPLL) 1762 p_rate = priv->cpll_hz; 1763 else if (src == CLK_UART_SEL_AUPLL) 1764 p_rate = priv->aupll_hz; 1765 else if (src == CLK_UART_SEL_FRAC0) 1766 p_rate = rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_0); 1767 else if (src == CLK_UART_SEL_FRAC1) 1768 p_rate = rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_1); 1769 else if (src == CLK_UART_SEL_FRAC2) 1770 p_rate = rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_2); 1771 else 1772 p_rate = OSC_HZ; 1773 1774 return DIV_TO_RATE(p_rate, div); 1775 } 1776 1777 static ulong rk3576_uart_set_rate(struct rk3576_clk_priv *priv, 1778 ulong clk_id, ulong rate) 1779 { 1780 struct rk3576_cru *cru = priv->cru; 1781 u32 reg, clk_src = 0, div = 0; 1782 1783 if (!(priv->gpll_hz % rate)) { 1784 clk_src = CLK_UART_SEL_GPLL; 1785 div = DIV_ROUND_UP(priv->gpll_hz, rate); 1786 } else if (!(priv->cpll_hz % rate)) { 1787 clk_src = CLK_UART_SEL_CPLL; 1788 div = DIV_ROUND_UP(priv->gpll_hz, rate); 1789 } else if (!(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_0) % rate)) { 1790 clk_src = CLK_UART_SEL_FRAC0; 1791 div = DIV_ROUND_UP(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_0), rate); 1792 } else if (!(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_1) % rate)) { 1793 clk_src = CLK_UART_SEL_FRAC1; 1794 div = DIV_ROUND_UP(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_1), rate); 1795 } else if (!(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_2) % rate)) { 1796 clk_src = CLK_UART_SEL_FRAC2; 1797 div = DIV_ROUND_UP(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_2), rate); 1798 } else if (!(OSC_HZ % rate)) { 1799 clk_src = CLK_UART_SEL_OSC; 1800 div = DIV_ROUND_UP(OSC_HZ, rate); 1801 } 1802 1803 switch (clk_id) { 1804 case SCLK_UART0: 1805 reg = 60; 1806 break; 1807 case SCLK_UART1: 1808 if (rate == OSC_HZ) { 1809 rk_clrsetreg(&cru->pmuclksel_con[8], 1810 CLK_UART1_SEL_MASK, 1811 (CLK_UART1_SEL_OSC << CLK_UART1_SEL_SHIFT)); 1812 return 0; 1813 } else { 1814 rk_clrsetreg(&cru->clksel_con[27], 1815 CLK_UART1_SRC_SEL_MASK | 1816 CLK_UART1_SRC_DIV_MASK, 1817 (clk_src << CLK_UART1_SRC_SEL_SHIFT) | 1818 ((div - 1) << CLK_UART1_SRC_DIV_SHIFT)); 1819 rk_clrsetreg(&cru->pmuclksel_con[8], 1820 CLK_UART1_SEL_MASK, 1821 (CLK_UART1_SEL_TOP << CLK_UART1_SEL_SHIFT)); 1822 return 0; 1823 } 1824 break; 1825 case SCLK_UART2: 1826 reg = 61; 1827 break; 1828 case SCLK_UART3: 1829 reg = 62; 1830 break; 1831 case SCLK_UART4: 1832 reg = 63; 1833 break; 1834 case SCLK_UART5: 1835 reg = 64; 1836 break; 1837 case SCLK_UART6: 1838 reg = 65; 1839 break; 1840 case SCLK_UART7: 1841 reg = 66; 1842 break; 1843 case SCLK_UART8: 1844 reg = 67; 1845 break; 1846 case SCLK_UART9: 1847 reg = 68; 1848 break; 1849 case SCLK_UART10: 1850 reg = 69; 1851 break; 1852 case SCLK_UART11: 1853 reg = 70; 1854 break; 1855 default: 1856 return -ENOENT; 1857 } 1858 rk_clrsetreg(&cru->clksel_con[reg], 1859 CLK_UART_SEL_MASK | 1860 CLK_UART_DIV_MASK, 1861 (clk_src << CLK_UART_SEL_SHIFT) | 1862 ((div - 1) << CLK_UART_DIV_SHIFT)); 1863 1864 return rk3576_uart_get_rate(priv, clk_id); 1865 } 1866 #endif 1867 1868 static ulong rk3576_ufs_ref_get_rate(struct rk3576_clk_priv *priv, ulong clk_id) 1869 { 1870 struct rk3576_cru *cru = priv->cru; 1871 u32 src, div; 1872 1873 src = readl(&cru->pmuclksel_con[3]) & 0x3; 1874 div= readl(&cru->pmuclksel_con[1]) & 0xff; 1875 if (src == 0) 1876 return OSC_HZ; 1877 else if (src == 2) 1878 return priv->ppll_hz / (div + 1); 1879 else 1880 return 26000000; 1881 1882 } 1883 1884 static ulong rk3576_clk_get_rate(struct clk *clk) 1885 { 1886 struct rk3576_clk_priv *priv = dev_get_priv(clk->dev); 1887 ulong rate = 0; 1888 1889 if (!priv->gpll_hz) { 1890 printf("%s gpll=%lu\n", __func__, priv->gpll_hz); 1891 return -ENOENT; 1892 } 1893 1894 if (!priv->ppll_hz) { 1895 priv->ppll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[PPLL], 1896 priv->cru, PPLL); 1897 } 1898 1899 switch (clk->id) { 1900 case PLL_LPLL: 1901 rate = rockchip_pll_get_rate(&rk3576_pll_clks[LPLL], priv->cru, 1902 LPLL); 1903 priv->lpll_hz = rate; 1904 break; 1905 case PLL_BPLL: 1906 rate = rockchip_pll_get_rate(&rk3576_pll_clks[BPLL], priv->cru, 1907 BPLL); 1908 priv->bpll_hz = rate; 1909 break; 1910 case PLL_GPLL: 1911 rate = rockchip_pll_get_rate(&rk3576_pll_clks[GPLL], priv->cru, 1912 GPLL); 1913 break; 1914 case PLL_CPLL: 1915 rate = rockchip_pll_get_rate(&rk3576_pll_clks[CPLL], priv->cru, 1916 CPLL); 1917 break; 1918 case PLL_VPLL: 1919 rate = rockchip_pll_get_rate(&rk3576_pll_clks[VPLL], priv->cru, 1920 VPLL); 1921 break; 1922 case PLL_AUPLL: 1923 rate = rockchip_pll_get_rate(&rk3576_pll_clks[AUPLL], priv->cru, 1924 AUPLL); 1925 break; 1926 case PLL_PPLL: 1927 rate = rockchip_pll_get_rate(&rk3576_pll_clks[PPLL], priv->cru, 1928 PPLL) * 2; 1929 break; 1930 case ACLK_BUS_ROOT: 1931 case HCLK_BUS_ROOT: 1932 case PCLK_BUS_ROOT: 1933 rate = rk3576_bus_get_clk(priv, clk->id); 1934 break; 1935 case ACLK_TOP: 1936 case HCLK_TOP: 1937 case PCLK_TOP_ROOT: 1938 case ACLK_TOP_MID: 1939 rate = rk3576_top_get_clk(priv, clk->id); 1940 break; 1941 case CLK_I2C0: 1942 case CLK_I2C1: 1943 case CLK_I2C2: 1944 case CLK_I2C3: 1945 case CLK_I2C4: 1946 case CLK_I2C5: 1947 case CLK_I2C6: 1948 case CLK_I2C7: 1949 case CLK_I2C8: 1950 case CLK_I2C9: 1951 rate = rk3576_i2c_get_clk(priv, clk->id); 1952 break; 1953 case CLK_SPI0: 1954 case CLK_SPI1: 1955 case CLK_SPI2: 1956 case CLK_SPI3: 1957 case CLK_SPI4: 1958 rate = rk3576_spi_get_clk(priv, clk->id); 1959 break; 1960 case CLK_PWM1: 1961 case CLK_PWM2: 1962 case CLK_PMU1PWM: 1963 rate = rk3576_pwm_get_clk(priv, clk->id); 1964 break; 1965 case CLK_SARADC: 1966 case CLK_TSADC: 1967 rate = rk3576_adc_get_clk(priv, clk->id); 1968 break; 1969 case CCLK_SRC_SDIO: 1970 case CCLK_SRC_SDMMC0: 1971 case CCLK_SRC_EMMC: 1972 case BCLK_EMMC: 1973 case SCLK_FSPI_X2: 1974 case SCLK_FSPI1_X2: 1975 case DCLK_DECOM: 1976 case HCLK_SDMMC0: 1977 case HCLK_EMMC: 1978 case HCLK_SDIO: 1979 rate = rk3576_mmc_get_clk(priv, clk->id); 1980 break; 1981 case TCLK_WDT0: 1982 rate = OSC_HZ; 1983 break; 1984 #ifndef CONFIG_SPL_BUILD 1985 case ACLK_VOP_ROOT: 1986 case ACLK_VOP: 1987 case ACLK_VO0_ROOT: 1988 case ACLK_VO1_ROOT: 1989 case HCLK_VOP_ROOT: 1990 case PCLK_VOP_ROOT: 1991 rate = rk3576_aclk_vop_get_clk(priv, clk->id); 1992 break; 1993 case DCLK_VP0: 1994 case DCLK_VP0_SRC: 1995 case DCLK_VP1: 1996 case DCLK_VP1_SRC: 1997 case DCLK_VP2: 1998 case DCLK_VP2_SRC: 1999 rate = rk3576_dclk_vop_get_clk(priv, clk->id); 2000 break; 2001 case CLK_GMAC0_PTP_REF_SRC: 2002 case CLK_GMAC1_PTP_REF_SRC: 2003 case CLK_GMAC0_PTP_REF: 2004 case CLK_GMAC1_PTP_REF: 2005 case CLK_GMAC0_125M_SRC: 2006 case CLK_GMAC1_125M_SRC: 2007 rate = rk3576_gmac_get_clk(priv, clk->id); 2008 break; 2009 case CLK_UART_FRAC_0: 2010 case CLK_UART_FRAC_1: 2011 case CLK_UART_FRAC_2: 2012 rate = rk3576_uart_frac_get_rate(priv, clk->id); 2013 break; 2014 case SCLK_UART0: 2015 case SCLK_UART1: 2016 case SCLK_UART2: 2017 case SCLK_UART3: 2018 case SCLK_UART4: 2019 case SCLK_UART5: 2020 case SCLK_UART6: 2021 case SCLK_UART7: 2022 case SCLK_UART8: 2023 case SCLK_UART9: 2024 case SCLK_UART10: 2025 case SCLK_UART11: 2026 rate = rk3576_uart_get_rate(priv, clk->id); 2027 break; 2028 case CLK_DSIHOST0: 2029 rate = rk3576_clk_csihost_get_clk(priv, clk->id); 2030 break; 2031 case DCLK_EBC: 2032 case DCLK_EBC_FRAC_SRC: 2033 rate = rk3576_dclk_ebc_get_clk(priv, clk->id); 2034 break; 2035 #endif 2036 case CLK_REF_UFS_CLKOUT: 2037 case CLK_REF_OSC_MPHY: 2038 rate = rk3576_ufs_ref_get_rate(priv, clk->id); 2039 break; 2040 2041 default: 2042 return -ENOENT; 2043 } 2044 2045 return rate; 2046 }; 2047 2048 static ulong rk3576_clk_set_rate(struct clk *clk, ulong rate) 2049 { 2050 struct rk3576_clk_priv *priv = dev_get_priv(clk->dev); 2051 ulong ret = 0; 2052 2053 if (!priv->ppll_hz) { 2054 priv->ppll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[PPLL], 2055 priv->cru, PPLL); 2056 } 2057 if (!priv->aupll_hz) { 2058 priv->aupll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[AUPLL], 2059 priv->cru, AUPLL); 2060 } 2061 2062 switch (clk->id) { 2063 case PLL_CPLL: 2064 ret = rockchip_pll_set_rate(&rk3576_pll_clks[CPLL], priv->cru, 2065 CPLL, rate); 2066 priv->cpll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[CPLL], 2067 priv->cru, CPLL); 2068 break; 2069 case PLL_GPLL: 2070 ret = rockchip_pll_set_rate(&rk3576_pll_clks[GPLL], priv->cru, 2071 GPLL, rate); 2072 priv->gpll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[GPLL], 2073 priv->cru, GPLL); 2074 break; 2075 case PLL_VPLL: 2076 ret = rockchip_pll_set_rate(&rk3576_pll_clks[VPLL], priv->cru, 2077 VPLL, rate); 2078 priv->vpll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[VPLL], 2079 priv->cru, VPLL); 2080 break; 2081 case PLL_AUPLL: 2082 ret = rockchip_pll_set_rate(&rk3576_pll_clks[AUPLL], priv->cru, 2083 AUPLL, rate); 2084 priv->aupll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[AUPLL], 2085 priv->cru, AUPLL); 2086 break; 2087 case PLL_PPLL: 2088 ret = rockchip_pll_set_rate(&rk3576_pll_clks[PPLL], priv->cru, 2089 PPLL, rate); 2090 priv->ppll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[PPLL], 2091 priv->cru, PPLL) * 2; 2092 break; 2093 case ACLK_BUS_ROOT: 2094 case HCLK_BUS_ROOT: 2095 case PCLK_BUS_ROOT: 2096 ret = rk3576_bus_set_clk(priv, clk->id, rate); 2097 break; 2098 case ACLK_TOP: 2099 case HCLK_TOP: 2100 case PCLK_TOP_ROOT: 2101 case ACLK_TOP_MID: 2102 ret = rk3576_top_set_clk(priv, clk->id, rate); 2103 break; 2104 case CLK_I2C0: 2105 case CLK_I2C1: 2106 case CLK_I2C2: 2107 case CLK_I2C3: 2108 case CLK_I2C4: 2109 case CLK_I2C5: 2110 case CLK_I2C6: 2111 case CLK_I2C7: 2112 case CLK_I2C8: 2113 case CLK_I2C9: 2114 ret = rk3576_i2c_set_clk(priv, clk->id, rate); 2115 break; 2116 case CLK_SPI0: 2117 case CLK_SPI1: 2118 case CLK_SPI2: 2119 case CLK_SPI3: 2120 case CLK_SPI4: 2121 ret = rk3576_spi_set_clk(priv, clk->id, rate); 2122 break; 2123 case CLK_PWM1: 2124 case CLK_PWM2: 2125 case CLK_PMU1PWM: 2126 ret = rk3576_pwm_set_clk(priv, clk->id, rate); 2127 break; 2128 case CLK_SARADC: 2129 case CLK_TSADC: 2130 ret = rk3576_adc_set_clk(priv, clk->id, rate); 2131 break; 2132 case CCLK_SRC_SDIO: 2133 case CCLK_SRC_SDMMC0: 2134 case CCLK_SRC_EMMC: 2135 case BCLK_EMMC: 2136 case SCLK_FSPI_X2: 2137 case SCLK_FSPI1_X2: 2138 case DCLK_DECOM: 2139 case HCLK_SDMMC0: 2140 case HCLK_EMMC: 2141 case HCLK_SDIO: 2142 ret = rk3576_mmc_set_clk(priv, clk->id, rate); 2143 break; 2144 case TCLK_WDT0: 2145 ret = OSC_HZ; 2146 break; 2147 #ifndef CONFIG_SPL_BUILD 2148 case ACLK_VOP_ROOT: 2149 case ACLK_VOP: 2150 case ACLK_VO0_ROOT: 2151 case ACLK_VO1_ROOT: 2152 case HCLK_VOP_ROOT: 2153 case PCLK_VOP_ROOT: 2154 ret = rk3576_aclk_vop_set_clk(priv, clk->id, rate); 2155 break; 2156 case DCLK_VP0: 2157 case DCLK_VP0_SRC: 2158 case DCLK_VP1: 2159 case DCLK_VP1_SRC: 2160 case DCLK_VP2: 2161 case DCLK_VP2_SRC: 2162 ret = rk3576_dclk_vop_set_clk(priv, clk->id, rate); 2163 break; 2164 case CLK_GMAC0_PTP_REF_SRC: 2165 case CLK_GMAC1_PTP_REF_SRC: 2166 case CLK_GMAC0_PTP_REF: 2167 case CLK_GMAC1_PTP_REF: 2168 case CLK_GMAC0_125M_SRC: 2169 case CLK_GMAC1_125M_SRC: 2170 ret = rk3576_gmac_set_clk(priv, clk->id, rate); 2171 break; 2172 case CLK_UART_FRAC_0: 2173 case CLK_UART_FRAC_1: 2174 case CLK_UART_FRAC_2: 2175 ret = rk3576_uart_frac_set_rate(priv, clk->id, rate); 2176 break; 2177 case SCLK_UART0: 2178 case SCLK_UART1: 2179 case SCLK_UART2: 2180 case SCLK_UART3: 2181 case SCLK_UART4: 2182 case SCLK_UART5: 2183 case SCLK_UART6: 2184 case SCLK_UART7: 2185 case SCLK_UART8: 2186 case SCLK_UART9: 2187 case SCLK_UART10: 2188 case SCLK_UART11: 2189 ret = rk3576_uart_set_rate(priv, clk->id, rate); 2190 break; 2191 case CLK_DSIHOST0: 2192 ret = rk3576_clk_csihost_set_clk(priv, clk->id, rate); 2193 break; 2194 case DCLK_EBC: 2195 case DCLK_EBC_FRAC_SRC: 2196 ret = rk3576_dclk_ebc_set_clk(priv, clk->id, rate); 2197 break; 2198 #endif 2199 default: 2200 return -ENOENT; 2201 } 2202 2203 return ret; 2204 }; 2205 2206 #if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA)) 2207 static int __maybe_unused rk3576_dclk_vop_set_parent(struct clk *clk, 2208 struct clk *parent) 2209 { 2210 struct rk3576_clk_priv *priv = dev_get_priv(clk->dev); 2211 struct rk3576_cru *cru = priv->cru; 2212 u32 sel; 2213 const char *clock_dev_name = parent->dev->name; 2214 2215 if (parent->id == PLL_VPLL) 2216 sel = 2; 2217 else if (parent->id == PLL_GPLL) 2218 sel = 0; 2219 else if (parent->id == PLL_CPLL) 2220 sel = 1; 2221 else if (parent->id == PLL_BPLL) 2222 sel = 3; 2223 else 2224 sel = 4; 2225 2226 switch (clk->id) { 2227 case DCLK_VP0_SRC: 2228 rk_clrsetreg(&cru->clksel_con[145], DCLK0_VOP_SRC_SEL_MASK, 2229 sel << DCLK0_VOP_SRC_SEL_SHIFT); 2230 break; 2231 case DCLK_VP1_SRC: 2232 rk_clrsetreg(&cru->clksel_con[146], DCLK0_VOP_SRC_SEL_MASK, 2233 sel << DCLK0_VOP_SRC_SEL_SHIFT); 2234 break; 2235 case DCLK_VP2_SRC: 2236 rk_clrsetreg(&cru->clksel_con[147], DCLK0_VOP_SRC_SEL_MASK, 2237 sel << DCLK0_VOP_SRC_SEL_SHIFT); 2238 break; 2239 case DCLK_VP0: 2240 if (!strcmp(clock_dev_name, "hdmiphypll_clk0")) 2241 sel = 1; 2242 else 2243 sel = 0; 2244 rk_clrsetreg(&cru->clksel_con[147], DCLK0_VOP_SEL_MASK, 2245 sel << DCLK0_VOP_SEL_SHIFT); 2246 break; 2247 case DCLK_VP1: 2248 if (!strcmp(clock_dev_name, "hdmiphypll_clk0")) 2249 sel = 1; 2250 else 2251 sel = 0; 2252 rk_clrsetreg(&cru->clksel_con[147], DCLK1_VOP_SEL_MASK, 2253 sel << DCLK1_VOP_SEL_SHIFT); 2254 break; 2255 case DCLK_VP2: 2256 if (!strcmp(clock_dev_name, "hdmiphypll_clk0")) 2257 sel = 1; 2258 else 2259 sel = 0; 2260 rk_clrsetreg(&cru->clksel_con[147], DCLK2_VOP_SEL_MASK, 2261 sel << DCLK2_VOP_SEL_SHIFT); 2262 break; 2263 default: 2264 return -EINVAL; 2265 } 2266 return 0; 2267 } 2268 2269 static int __maybe_unused rk3576_ufs_ref_set_parent(struct clk *clk, 2270 struct clk *parent) 2271 { 2272 struct rk3576_clk_priv *priv = dev_get_priv(clk->dev); 2273 struct rk3576_cru *cru = priv->cru; 2274 u32 sel; 2275 const char *clock_dev_name = parent->dev->name; 2276 2277 if (parent->id == CLK_REF_MPHY_26M) 2278 sel = 2; 2279 else if (!strcmp(clock_dev_name, "xin24m")) 2280 sel = 0; 2281 else 2282 sel = 1; 2283 2284 rk_clrsetreg(&cru->pmuclksel_con[3], 0x3, sel << 0); 2285 return 0; 2286 } 2287 2288 static int rk3576_clk_set_parent(struct clk *clk, struct clk *parent) 2289 { 2290 switch (clk->id) { 2291 case DCLK_VP0_SRC: 2292 case DCLK_VP1_SRC: 2293 case DCLK_VP2_SRC: 2294 case DCLK_VP0: 2295 case DCLK_VP1: 2296 case DCLK_VP2: 2297 return rk3576_dclk_vop_set_parent(clk, parent); 2298 case CLK_REF_OSC_MPHY: 2299 return rk3576_ufs_ref_set_parent(clk, parent); 2300 2301 default: 2302 return -ENOENT; 2303 } 2304 2305 return 0; 2306 } 2307 #endif 2308 2309 static struct clk_ops rk3576_clk_ops = { 2310 .get_rate = rk3576_clk_get_rate, 2311 .set_rate = rk3576_clk_set_rate, 2312 #if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA)) 2313 .set_parent = rk3576_clk_set_parent, 2314 #endif 2315 }; 2316 2317 static void rk3576_clk_init(struct rk3576_clk_priv *priv) 2318 { 2319 int ret; 2320 2321 priv->spll_hz = 702000000; 2322 2323 if (priv->cpll_hz != CPLL_HZ) { 2324 ret = rockchip_pll_set_rate(&rk3576_pll_clks[CPLL], priv->cru, 2325 CPLL, CPLL_HZ); 2326 if (!ret) 2327 priv->cpll_hz = CPLL_HZ; 2328 } 2329 if (priv->gpll_hz != GPLL_HZ) { 2330 ret = rockchip_pll_set_rate(&rk3576_pll_clks[GPLL], priv->cru, 2331 GPLL, GPLL_HZ); 2332 if (!ret) 2333 priv->gpll_hz = GPLL_HZ; 2334 } 2335 } 2336 2337 static int rk3576_clk_probe(struct udevice *dev) 2338 { 2339 struct rk3576_clk_priv *priv = dev_get_priv(dev); 2340 int ret; 2341 #if CONFIG_IS_ENABLED(CLK_SCMI) 2342 struct clk clk; 2343 #endif 2344 2345 priv->sync_kernel = false; 2346 2347 #ifdef CONFIG_SPL_BUILD 2348 /* relase presetn_bigcore_biu/cru/grf */ 2349 writel(0x1c001c00, 0x26010010); 2350 /* set spll to normal mode */ 2351 writel(BITS_WITH_WMASK(2, 0x7U, 6), 2352 RK3576_SCRU_BASE + RK3576_PLL_CON(137)); 2353 writel(BITS_WITH_WMASK(1, 0x3U, 0), 2354 RK3576_SCRU_BASE + RK3576_MODE_CON0); 2355 /* fix ppll\aupll\cpll */ 2356 writel(BITS_WITH_WMASK(2, 0x7U, 6), 2357 RK3576_CRU_BASE + RK3576_PMU_PLL_CON(129)); 2358 writel(BITS_WITH_WMASK(2, 0x7U, 6), 2359 RK3576_CRU_BASE + RK3576_PLL_CON(97)); 2360 writel(BITS_WITH_WMASK(2, 0x7U, 6), 2361 RK3576_CRU_BASE + RK3576_PLL_CON(105)); 2362 writel(BITS_WITH_WMASK(1, 0x3U, 6), 2363 RK3576_CRU_BASE + RK3576_MODE_CON0); 2364 writel(BITS_WITH_WMASK(1, 0x3U, 8), 2365 RK3576_CRU_BASE + RK3576_MODE_CON0); 2366 /* init cci */ 2367 writel(0xffff0000, RK3576_CRU_BASE + RK3576_CCI_CLKSEL_CON(4)); 2368 rockchip_pll_set_rate(&rk3576_pll_clks[BPLL], priv->cru, 2369 BPLL, LPLL_HZ); 2370 if (!priv->armclk_enter_hz) { 2371 ret = rockchip_pll_set_rate(&rk3576_pll_clks[LPLL], priv->cru, 2372 LPLL, LPLL_HZ); 2373 priv->armclk_enter_hz = 2374 rockchip_pll_get_rate(&rk3576_pll_clks[LPLL], 2375 priv->cru, LPLL); 2376 priv->armclk_init_hz = priv->armclk_enter_hz; 2377 rk_clrsetreg(&priv->cru->litclksel_con[0], CLK_LITCORE_DIV_MASK, 2378 0 << CLK_LITCORE_DIV_SHIFT); 2379 } 2380 /* init cci */ 2381 writel(0xffff20cb, RK3576_CRU_BASE + RK3576_CCI_CLKSEL_CON(4)); 2382 2383 /* Change bigcore rm from 4 to 3 */ 2384 writel(0x001c000c, RK3576_BIGCORE_GRF_BASE + 0x3c); 2385 writel(0x001c000c, RK3576_BIGCORE_GRF_BASE + 0x44); 2386 writel(0x00020002, RK3576_BIGCORE_GRF_BASE + 0x38); 2387 udelay(1); 2388 writel(0x00020000, RK3576_BIGCORE_GRF_BASE + 0x38); 2389 /* Change litcore rm from 4 to 3 */ 2390 writel(0x001c000c, RK3576_LITCORE_GRF_BASE + 0x3c); 2391 writel(0x001c000c, RK3576_LITCORE_GRF_BASE + 0x44); 2392 writel(0x00020002, RK3576_LITCORE_GRF_BASE + 0x38); 2393 udelay(1); 2394 writel(0x00020000, RK3576_LITCORE_GRF_BASE + 0x38); 2395 /* Change cci rm form 4 to 3 */ 2396 writel(0x001c000c, RK3576_CCI_GRF_BASE + 0x54); 2397 #endif 2398 2399 priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 2400 if (IS_ERR(priv->grf)) 2401 return PTR_ERR(priv->grf); 2402 2403 rk3576_clk_init(priv); 2404 2405 #if CONFIG_IS_ENABLED(CLK_SCMI) 2406 #ifndef CONFIG_SPL_BUILD 2407 ret = rockchip_get_scmi_clk(&clk.dev); 2408 if (ret) { 2409 printf("Failed to get scmi clk dev, ret=%d\n", ret); 2410 return ret; 2411 } 2412 if (!priv->armclk_enter_hz) { 2413 clk.id = ARMCLK_L; 2414 ret = clk_set_rate(&clk, CPU_PVTPLL_HZ); 2415 if (ret < 0) { 2416 printf("Failed to set cpubl, ret=%d\n", ret); 2417 } else { 2418 priv->armclk_enter_hz = CPU_PVTPLL_HZ; 2419 priv->armclk_init_hz = CPU_PVTPLL_HZ; 2420 } 2421 } 2422 clk.id = ARMCLK_B; 2423 ret = clk_set_rate(&clk, CPU_PVTPLL_HZ); 2424 if (ret < 0) 2425 printf("Failed to set cpub, ret=%d\n", ret); 2426 #endif 2427 #endif 2428 2429 /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */ 2430 ret = clk_set_defaults(dev); 2431 if (ret) 2432 debug("%s clk_set_defaults failed %d\n", __func__, ret); 2433 else 2434 priv->sync_kernel = true; 2435 2436 return 0; 2437 } 2438 2439 static int rk3576_clk_ofdata_to_platdata(struct udevice *dev) 2440 { 2441 struct rk3576_clk_priv *priv = dev_get_priv(dev); 2442 2443 priv->cru = dev_read_addr_ptr(dev); 2444 2445 return 0; 2446 } 2447 2448 static int rk3576_clk_bind(struct udevice *dev) 2449 { 2450 int ret; 2451 struct udevice *sys_child, *sf_child; 2452 struct sysreset_reg *priv; 2453 struct softreset_reg *sf_priv; 2454 2455 /* The reset driver does not have a device node, so bind it here */ 2456 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset", 2457 &sys_child); 2458 if (ret) { 2459 debug("Warning: No sysreset driver: ret=%d\n", ret); 2460 } else { 2461 priv = malloc(sizeof(struct sysreset_reg)); 2462 priv->glb_srst_fst_value = offsetof(struct rk3576_cru, 2463 glb_srst_fst); 2464 priv->glb_srst_snd_value = offsetof(struct rk3576_cru, 2465 glb_srsr_snd); 2466 sys_child->priv = priv; 2467 } 2468 2469 ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset", 2470 dev_ofnode(dev), &sf_child); 2471 if (ret) { 2472 debug("Warning: No rockchip reset driver: ret=%d\n", ret); 2473 } else { 2474 sf_priv = malloc(sizeof(struct softreset_reg)); 2475 sf_priv->sf_reset_offset = offsetof(struct rk3576_cru, 2476 softrst_con[0]); 2477 sf_priv->sf_reset_num = 524454; 2478 sf_child->priv = sf_priv; 2479 } 2480 2481 return 0; 2482 } 2483 2484 static const struct udevice_id rk3576_clk_ids[] = { 2485 { .compatible = "rockchip,rk3576-cru" }, 2486 { } 2487 }; 2488 2489 U_BOOT_DRIVER(rockchip_rk3576_cru) = { 2490 .name = "rockchip_rk3576_cru", 2491 .id = UCLASS_CLK, 2492 .of_match = rk3576_clk_ids, 2493 .priv_auto_alloc_size = sizeof(struct rk3576_clk_priv), 2494 .ofdata_to_platdata = rk3576_clk_ofdata_to_platdata, 2495 .ops = &rk3576_clk_ops, 2496 .bind = rk3576_clk_bind, 2497 .probe = rk3576_clk_probe, 2498 }; 2499 2500 #ifndef CONFIG_SPL_BUILD 2501 /** 2502 * soc_clk_dump() - Print clock frequencies 2503 * Returns zero on success 2504 * 2505 * Implementation for the clk dump command. 2506 */ 2507 int soc_clk_dump(void) 2508 { 2509 struct udevice *cru_dev; 2510 struct rk3576_clk_priv *priv; 2511 const struct rk3576_clk_info *clk_dump; 2512 struct clk clk; 2513 unsigned long clk_count = ARRAY_SIZE(clks_dump); 2514 unsigned long rate; 2515 int i, ret; 2516 2517 ret = uclass_get_device_by_driver(UCLASS_CLK, 2518 DM_GET_DRIVER(rockchip_rk3576_cru), 2519 &cru_dev); 2520 if (ret) { 2521 printf("%s failed to get cru device\n", __func__); 2522 return ret; 2523 } 2524 2525 priv = dev_get_priv(cru_dev); 2526 printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n", 2527 priv->sync_kernel ? "sync kernel" : "uboot", 2528 priv->armclk_enter_hz / 1000, 2529 priv->armclk_init_hz / 1000, 2530 priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0, 2531 priv->set_armclk_rate ? " KHz" : "N/A"); 2532 for (i = 0; i < clk_count; i++) { 2533 clk_dump = &clks_dump[i]; 2534 if (clk_dump->name) { 2535 memset(&clk, 0, sizeof(struct clk)); 2536 clk.id = clk_dump->id; 2537 if (clk_dump->is_cru) 2538 ret = clk_request(cru_dev, &clk); 2539 if (ret < 0) 2540 return ret; 2541 2542 rate = clk_get_rate(&clk); 2543 clk_free(&clk); 2544 if (rate < 0) 2545 printf(" %s %s\n", clk_dump->name, 2546 "unknown"); 2547 else 2548 printf(" %s %lu KHz\n", clk_dump->name, 2549 rate / 1000); 2550 } 2551 } 2552 2553 return 0; 2554 } 2555 #endif 2556