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 con = readl(&cru->clksel_con[104]); 769 div = (con & CCLK_SDIO_SRC_DIV_MASK) >> CCLK_SDIO_SRC_DIV_SHIFT; 770 sel = (con & CCLK_SDIO_SRC_SEL_MASK) >> 771 CCLK_SDIO_SRC_SEL_SHIFT; 772 if (sel == CCLK_SDIO_SRC_SEL_GPLL) 773 prate = priv->gpll_hz; 774 else if (sel == CCLK_SDIO_SRC_SEL_CPLL) 775 prate = priv->cpll_hz; 776 else 777 prate = OSC_HZ; 778 return DIV_TO_RATE(prate, div); 779 case CCLK_SRC_SDMMC0: 780 con = readl(&cru->clksel_con[105]); 781 div = (con & CCLK_SDMMC0_SRC_DIV_MASK) >> CCLK_SDMMC0_SRC_DIV_SHIFT; 782 sel = (con & CCLK_SDMMC0_SRC_SEL_MASK) >> 783 CCLK_SDMMC0_SRC_SEL_SHIFT; 784 if (sel == CCLK_SDMMC0_SRC_SEL_GPLL) 785 prate = priv->gpll_hz; 786 else if (sel == CCLK_SDMMC0_SRC_SEL_CPLL) 787 prate = priv->cpll_hz; 788 else 789 prate = OSC_HZ; 790 return DIV_TO_RATE(prate, div); 791 case CCLK_SRC_EMMC: 792 con = readl(&cru->clksel_con[89]); 793 div = (con & CCLK_EMMC_DIV_MASK) >> CCLK_EMMC_DIV_SHIFT; 794 sel = (con & CCLK_EMMC_SEL_MASK) >> 795 CCLK_EMMC_SEL_SHIFT; 796 if (sel == CCLK_EMMC_SEL_GPLL) 797 prate = priv->gpll_hz; 798 else if (sel == CCLK_EMMC_SEL_CPLL) 799 prate = priv->cpll_hz; 800 else 801 prate = OSC_HZ; 802 return DIV_TO_RATE(prate, div); 803 case BCLK_EMMC: 804 con = readl(&cru->clksel_con[90]); 805 sel = (con & BCLK_EMMC_SEL_MASK) >> 806 BCLK_EMMC_SEL_SHIFT; 807 if (sel == BCLK_EMMC_SEL_200M) 808 prate = 200 * MHz; 809 else if (sel == BCLK_EMMC_SEL_100M) 810 prate = 100 * MHz; 811 else if (sel == BCLK_EMMC_SEL_50M) 812 prate = 50 * MHz; 813 else 814 prate = OSC_HZ; 815 return DIV_TO_RATE(prate, div); 816 case SCLK_FSPI_X2: 817 con = readl(&cru->clksel_con[89]); 818 div = (con & SCLK_FSPI_DIV_MASK) >> SCLK_FSPI_DIV_SHIFT; 819 sel = (con & SCLK_FSPI_SEL_MASK) >> 820 SCLK_FSPI_SEL_SHIFT; 821 if (sel == SCLK_FSPI_SEL_GPLL) 822 prate = priv->gpll_hz; 823 else if (sel == SCLK_FSPI_SEL_CPLL) 824 prate = priv->cpll_hz; 825 else 826 prate = OSC_HZ; 827 return DIV_TO_RATE(prate, div); 828 case SCLK_FSPI1_X2: 829 con = readl(&cru->clksel_con[106]); 830 div = (con & SCLK_FSPI_DIV_MASK) >> SCLK_FSPI_DIV_SHIFT; 831 sel = (con & SCLK_FSPI_SEL_MASK) >> 832 SCLK_FSPI_SEL_SHIFT; 833 if (sel == SCLK_FSPI_SEL_GPLL) 834 prate = priv->gpll_hz; 835 else if (sel == SCLK_FSPI_SEL_CPLL) 836 prate = priv->cpll_hz; 837 else 838 prate = OSC_HZ; 839 return DIV_TO_RATE(prate, div); 840 default: 841 return -ENOENT; 842 } 843 } 844 845 static ulong rk3576_mmc_set_clk(struct rk3576_clk_priv *priv, 846 ulong clk_id, ulong rate) 847 { 848 struct rk3576_cru *cru = priv->cru; 849 int src_clk, div = 0; 850 851 switch (clk_id) { 852 case CCLK_SRC_SDIO: 853 case CCLK_SRC_SDMMC0: 854 case CCLK_SRC_EMMC: 855 case SCLK_FSPI_X2: 856 case SCLK_FSPI1_X2: 857 if (!(OSC_HZ % rate)) { 858 src_clk = SCLK_FSPI_SEL_OSC; 859 div = DIV_ROUND_UP(OSC_HZ, rate); 860 } else if (!(priv->cpll_hz % rate)) { 861 src_clk = SCLK_FSPI_SEL_CPLL; 862 div = DIV_ROUND_UP(priv->cpll_hz, rate); 863 } else { 864 src_clk = SCLK_FSPI_SEL_GPLL; 865 div = DIV_ROUND_UP(priv->gpll_hz, rate); 866 } 867 break; 868 case BCLK_EMMC: 869 if (rate >= 198 * MHz) 870 src_clk = BCLK_EMMC_SEL_200M; 871 else if (rate >= 99 * MHz) 872 src_clk = BCLK_EMMC_SEL_100M; 873 else if (rate >= 50 * MHz) 874 src_clk = BCLK_EMMC_SEL_50M; 875 else 876 src_clk = BCLK_EMMC_SEL_OSC; 877 break; 878 default: 879 return -ENOENT; 880 } 881 882 switch (clk_id) { 883 case CCLK_SRC_SDIO: 884 rk_clrsetreg(&cru->clksel_con[104], 885 CCLK_SDIO_SRC_SEL_MASK | 886 CCLK_SDIO_SRC_DIV_MASK, 887 (src_clk << CCLK_SDIO_SRC_SEL_SHIFT) | 888 (div - 1) << CCLK_SDIO_SRC_DIV_SHIFT); 889 break; 890 case CCLK_SRC_SDMMC0: 891 rk_clrsetreg(&cru->clksel_con[105], 892 CCLK_EMMC_SEL_MASK | 893 CCLK_EMMC_DIV_MASK, 894 (src_clk << CCLK_EMMC_SEL_SHIFT) | 895 (div - 1) << CCLK_EMMC_DIV_SHIFT); 896 break; 897 case CCLK_SRC_EMMC: 898 rk_clrsetreg(&cru->clksel_con[89], 899 CCLK_EMMC_DIV_MASK | 900 CCLK_EMMC_SEL_MASK, 901 (src_clk << CCLK_EMMC_SEL_SHIFT) | 902 (div - 1) << CCLK_EMMC_DIV_SHIFT); 903 break; 904 case SCLK_FSPI_X2: 905 rk_clrsetreg(&cru->clksel_con[89], 906 SCLK_FSPI_DIV_MASK | 907 SCLK_FSPI_SEL_MASK, 908 (src_clk << SCLK_FSPI_SEL_SHIFT) | 909 (div - 1) << SCLK_FSPI_DIV_SHIFT); 910 break; 911 case SCLK_FSPI1_X2: 912 rk_clrsetreg(&cru->clksel_con[106], 913 SCLK_FSPI_DIV_MASK | 914 SCLK_FSPI_SEL_MASK, 915 (src_clk << SCLK_FSPI_SEL_SHIFT) | 916 (div - 1) << SCLK_FSPI_DIV_SHIFT); 917 break; 918 case BCLK_EMMC: 919 rk_clrsetreg(&cru->clksel_con[90], 920 BCLK_EMMC_SEL_MASK, 921 src_clk << BCLK_EMMC_SEL_SHIFT); 922 break; 923 default: 924 return -ENOENT; 925 } 926 927 return rk3576_mmc_get_clk(priv, clk_id); 928 } 929 930 #ifndef CONFIG_SPL_BUILD 931 932 static ulong rk3576_aclk_vop_get_clk(struct rk3576_clk_priv *priv, ulong clk_id) 933 { 934 struct rk3576_cru *cru = priv->cru; 935 u32 div, sel, con, parent = 0; 936 937 switch (clk_id) { 938 case ACLK_VOP_ROOT: 939 case ACLK_VOP: 940 con = readl(&cru->clksel_con[144]); 941 div = (con & ACLK_VOP_ROOT_DIV_MASK) >> ACLK_VOP_ROOT_DIV_SHIFT; 942 sel = (con & ACLK_VOP_ROOT_SEL_MASK) >> ACLK_VOP_ROOT_SEL_SHIFT; 943 if (sel == ACLK_VOP_ROOT_SEL_GPLL) 944 parent = priv->gpll_hz; 945 else if (sel == ACLK_VOP_ROOT_SEL_CPLL) 946 parent = priv->cpll_hz; 947 else if (sel == ACLK_VOP_ROOT_SEL_AUPLL) 948 parent = priv->aupll_hz; 949 else if (sel == ACLK_VOP_ROOT_SEL_SPLL) 950 parent = priv->spll_hz; 951 else if (sel == ACLK_VOP_ROOT_SEL_LPLL) 952 parent = priv->lpll_hz / 2; 953 return DIV_TO_RATE(parent, div); 954 case ACLK_VO0_ROOT: 955 con = readl(&cru->clksel_con[149]); 956 div = (con & ACLK_VO0_ROOT_DIV_MASK) >> ACLK_VO0_ROOT_DIV_SHIFT; 957 sel = (con & ACLK_VO0_ROOT_SEL_MASK) >> ACLK_VO0_ROOT_SEL_SHIFT; 958 if (sel == ACLK_VO0_ROOT_SEL_GPLL) 959 parent = priv->gpll_hz; 960 else if (sel == ACLK_VO0_ROOT_SEL_CPLL) 961 parent = priv->cpll_hz; 962 else if (sel == ACLK_VO0_ROOT_SEL_LPLL) 963 parent = priv->lpll_hz / 2; 964 else if (sel == ACLK_VO0_ROOT_SEL_BPLL) 965 parent = priv->bpll_hz / 4; 966 return DIV_TO_RATE(parent, div); 967 case ACLK_VO1_ROOT: 968 con = readl(&cru->clksel_con[158]); 969 div = (con & ACLK_VO0_ROOT_DIV_MASK) >> ACLK_VO0_ROOT_DIV_SHIFT; 970 sel = (con & ACLK_VO0_ROOT_SEL_MASK) >> ACLK_VO0_ROOT_SEL_SHIFT; 971 if (sel == ACLK_VO0_ROOT_SEL_GPLL) 972 parent = priv->gpll_hz; 973 else if (sel == ACLK_VO0_ROOT_SEL_CPLL) 974 parent = priv->cpll_hz; 975 else if (sel == ACLK_VO0_ROOT_SEL_LPLL) 976 parent = priv->lpll_hz / 2; 977 else if (sel == ACLK_VO0_ROOT_SEL_BPLL) 978 parent = priv->bpll_hz / 4; 979 return DIV_TO_RATE(parent, div); 980 case HCLK_VOP_ROOT: 981 con = readl(&cru->clksel_con[144]); 982 sel = (con & HCLK_VOP_ROOT_SEL_MASK) >> HCLK_VOP_ROOT_SEL_SHIFT; 983 if (sel == HCLK_VOP_ROOT_SEL_200M) 984 return 200 * MHz; 985 else if (sel == HCLK_VOP_ROOT_SEL_100M) 986 return 100 * MHz; 987 else if (sel == HCLK_VOP_ROOT_SEL_50M) 988 return 50 * MHz; 989 else 990 return OSC_HZ; 991 case PCLK_VOP_ROOT: 992 con = readl(&cru->clksel_con[144]); 993 sel = (con & PCLK_VOP_ROOT_SEL_MASK) >> PCLK_VOP_ROOT_SEL_SHIFT; 994 if (sel == PCLK_VOP_ROOT_SEL_100M) 995 return 100 * MHz; 996 else if (sel == PCLK_VOP_ROOT_SEL_50M) 997 return 50 * MHz; 998 else 999 return OSC_HZ; 1000 1001 default: 1002 return -ENOENT; 1003 } 1004 } 1005 1006 static ulong rk3576_aclk_vop_set_clk(struct rk3576_clk_priv *priv, 1007 ulong clk_id, ulong rate) 1008 { 1009 struct rk3576_cru *cru = priv->cru; 1010 int src_clk, div; 1011 1012 switch (clk_id) { 1013 case ACLK_VOP_ROOT: 1014 case ACLK_VOP: 1015 if (rate == 700 * MHz) { 1016 src_clk = ACLK_VOP_ROOT_SEL_SPLL; 1017 div = 1; 1018 } else if (!(priv->cpll_hz % rate)) { 1019 src_clk = ACLK_VOP_ROOT_SEL_CPLL; 1020 div = DIV_ROUND_UP(priv->cpll_hz, rate); 1021 } else { 1022 src_clk = ACLK_VOP_ROOT_SEL_GPLL; 1023 div = DIV_ROUND_UP(priv->gpll_hz, rate); 1024 } 1025 rk_clrsetreg(&cru->clksel_con[144], 1026 ACLK_VOP_ROOT_DIV_MASK | 1027 ACLK_VOP_ROOT_SEL_MASK, 1028 (src_clk << ACLK_VOP_ROOT_SEL_SHIFT) | 1029 (div - 1) << ACLK_VOP_ROOT_DIV_SHIFT); 1030 break; 1031 case ACLK_VO0_ROOT: 1032 if (!(priv->cpll_hz % rate)) { 1033 src_clk = ACLK_VO0_ROOT_SEL_CPLL; 1034 div = DIV_ROUND_UP(priv->cpll_hz, rate); 1035 } else { 1036 src_clk = ACLK_VO0_ROOT_SEL_GPLL; 1037 div = DIV_ROUND_UP(priv->gpll_hz, rate); 1038 } 1039 rk_clrsetreg(&cru->clksel_con[149], 1040 ACLK_VO0_ROOT_DIV_MASK | 1041 ACLK_VO0_ROOT_SEL_MASK, 1042 (src_clk << ACLK_VO0_ROOT_SEL_SHIFT) | 1043 (div - 1) << ACLK_VO0_ROOT_DIV_SHIFT); 1044 break; 1045 case ACLK_VO1_ROOT: 1046 if (!(priv->cpll_hz % rate)) { 1047 src_clk = ACLK_VO0_ROOT_SEL_CPLL; 1048 div = DIV_ROUND_UP(priv->cpll_hz, rate); 1049 } else { 1050 src_clk = ACLK_VO0_ROOT_SEL_GPLL; 1051 div = DIV_ROUND_UP(priv->gpll_hz, rate); 1052 } 1053 rk_clrsetreg(&cru->clksel_con[158], 1054 ACLK_VO0_ROOT_DIV_MASK | 1055 ACLK_VO0_ROOT_SEL_MASK, 1056 (src_clk << ACLK_VO0_ROOT_SEL_SHIFT) | 1057 (div - 1) << ACLK_VO0_ROOT_DIV_SHIFT); 1058 break; 1059 case HCLK_VOP_ROOT: 1060 if (rate == 200 * MHz) 1061 src_clk = HCLK_VOP_ROOT_SEL_200M; 1062 else if (rate == 100 * MHz) 1063 src_clk = HCLK_VOP_ROOT_SEL_100M; 1064 else if (rate == 50 * MHz) 1065 src_clk = HCLK_VOP_ROOT_SEL_50M; 1066 else 1067 src_clk = HCLK_VOP_ROOT_SEL_OSC; 1068 rk_clrsetreg(&cru->clksel_con[144], 1069 HCLK_VOP_ROOT_SEL_MASK, 1070 src_clk << HCLK_VOP_ROOT_SEL_SHIFT); 1071 break; 1072 case PCLK_VOP_ROOT: 1073 if (rate == 100 * MHz) 1074 src_clk = PCLK_VOP_ROOT_SEL_100M; 1075 else if (rate == 50 * MHz) 1076 src_clk = PCLK_VOP_ROOT_SEL_50M; 1077 else 1078 src_clk = PCLK_VOP_ROOT_SEL_OSC; 1079 rk_clrsetreg(&cru->clksel_con[144], 1080 PCLK_VOP_ROOT_SEL_MASK, 1081 src_clk << PCLK_VOP_ROOT_SEL_SHIFT); 1082 break; 1083 1084 default: 1085 return -ENOENT; 1086 } 1087 1088 return rk3576_aclk_vop_get_clk(priv, clk_id); 1089 } 1090 1091 static ulong rk3576_dclk_vop_get_clk(struct rk3576_clk_priv *priv, ulong clk_id) 1092 { 1093 struct rk3576_cru *cru = priv->cru; 1094 u32 div, sel, con, parent; 1095 1096 switch (clk_id) { 1097 case DCLK_VP0: 1098 case DCLK_VP0_SRC: 1099 con = readl(&cru->clksel_con[145]); 1100 div = (con & DCLK0_VOP_SRC_DIV_MASK) >> DCLK0_VOP_SRC_DIV_SHIFT; 1101 sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT; 1102 break; 1103 case DCLK_VP1: 1104 case DCLK_VP1_SRC: 1105 con = readl(&cru->clksel_con[146]); 1106 div = (con & DCLK0_VOP_SRC_DIV_MASK) >> DCLK0_VOP_SRC_DIV_SHIFT; 1107 sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT; 1108 break; 1109 case DCLK_VP2: 1110 case DCLK_VP2_SRC: 1111 con = readl(&cru->clksel_con[147]); 1112 div = (con & DCLK0_VOP_SRC_DIV_MASK) >> DCLK0_VOP_SRC_DIV_SHIFT; 1113 sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT; 1114 break; 1115 default: 1116 return -ENOENT; 1117 } 1118 1119 if (sel == DCLK_VOP_SRC_SEL_VPLL) 1120 parent = priv->vpll_hz; 1121 else if (sel == DCLK_VOP_SRC_SEL_BPLL) 1122 parent = priv->bpll_hz / 4; 1123 else if (sel == DCLK_VOP_SRC_SEL_LPLL) 1124 parent = priv->lpll_hz / 2; 1125 else if (sel == DCLK_VOP_SRC_SEL_GPLL) 1126 parent = priv->gpll_hz; 1127 else 1128 parent = priv->cpll_hz; 1129 1130 return DIV_TO_RATE(parent, div); 1131 } 1132 1133 #define RK3576_VOP_PLL_LIMIT_FREQ 600000000 1134 1135 static ulong rk3576_dclk_vop_set_clk(struct rk3576_clk_priv *priv, 1136 ulong clk_id, ulong rate) 1137 { 1138 struct rk3576_cru *cru = priv->cru; 1139 ulong pll_rate, now, best_rate = 0; 1140 u32 i, conid, con, sel, div, best_div = 0, best_sel = 0; 1141 u32 mask, div_shift, sel_shift; 1142 1143 switch (clk_id) { 1144 case DCLK_VP0: 1145 case DCLK_VP0_SRC: 1146 conid = 145; 1147 con = readl(&cru->clksel_con[conid]); 1148 sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT; 1149 mask = DCLK0_VOP_SRC_SEL_MASK | DCLK0_VOP_SRC_DIV_MASK; 1150 div_shift = DCLK0_VOP_SRC_DIV_SHIFT; 1151 sel_shift = DCLK0_VOP_SRC_SEL_SHIFT; 1152 break; 1153 case DCLK_VP1: 1154 case DCLK_VP1_SRC: 1155 conid = 146; 1156 con = readl(&cru->clksel_con[conid]); 1157 sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT; 1158 mask = DCLK0_VOP_SRC_SEL_MASK | DCLK0_VOP_SRC_DIV_MASK; 1159 div_shift = DCLK0_VOP_SRC_DIV_SHIFT; 1160 sel_shift = DCLK0_VOP_SRC_SEL_SHIFT; 1161 break; 1162 case DCLK_VP2: 1163 case DCLK_VP2_SRC: 1164 conid = 147; 1165 con = readl(&cru->clksel_con[conid]); 1166 sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT; 1167 mask = DCLK0_VOP_SRC_SEL_MASK | DCLK0_VOP_SRC_DIV_MASK; 1168 div_shift = DCLK0_VOP_SRC_DIV_SHIFT; 1169 sel_shift = DCLK0_VOP_SRC_SEL_SHIFT; 1170 break; 1171 default: 1172 return -ENOENT; 1173 } 1174 1175 if (sel == DCLK_VOP_SRC_SEL_VPLL) { 1176 pll_rate = rockchip_pll_get_rate(&rk3576_pll_clks[VPLL], 1177 priv->cru, VPLL); 1178 if (pll_rate >= RK3576_VOP_PLL_LIMIT_FREQ && pll_rate % rate == 0) { 1179 div = DIV_ROUND_UP(pll_rate, rate); 1180 rk_clrsetreg(&cru->clksel_con[conid], 1181 mask, 1182 DCLK_VOP_SRC_SEL_VPLL << sel_shift | 1183 ((div - 1) << div_shift)); 1184 } else { 1185 div = DIV_ROUND_UP(RK3576_VOP_PLL_LIMIT_FREQ, rate); 1186 if (div % 2) 1187 div = div + 1; 1188 rk_clrsetreg(&cru->clksel_con[conid], 1189 mask, 1190 DCLK_VOP_SRC_SEL_VPLL << sel_shift | 1191 ((div - 1) << div_shift)); 1192 rockchip_pll_set_rate(&rk3576_pll_clks[VPLL], 1193 priv->cru, VPLL, div * rate); 1194 priv->vpll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[VPLL], 1195 priv->cru, VPLL); 1196 } 1197 } else { 1198 for (i = 0; i <= DCLK_VOP_SRC_SEL_LPLL; i++) { 1199 switch (i) { 1200 case DCLK_VOP_SRC_SEL_GPLL: 1201 pll_rate = priv->gpll_hz; 1202 break; 1203 case DCLK_VOP_SRC_SEL_CPLL: 1204 pll_rate = priv->cpll_hz; 1205 break; 1206 case DCLK_VOP_SRC_SEL_BPLL: 1207 pll_rate = 0; 1208 break; 1209 case DCLK_VOP_SRC_SEL_LPLL: 1210 pll_rate = 0; 1211 break; 1212 case DCLK_VOP_SRC_SEL_VPLL: 1213 pll_rate = 0; 1214 break; 1215 default: 1216 printf("do not support this vop pll sel\n"); 1217 return -EINVAL; 1218 } 1219 1220 div = DIV_ROUND_UP(pll_rate, rate); 1221 if (div > 255) 1222 continue; 1223 now = pll_rate / div; 1224 if (abs(rate - now) < abs(rate - best_rate)) { 1225 best_rate = now; 1226 best_div = div; 1227 best_sel = i; 1228 } 1229 debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n", 1230 pll_rate, best_rate, best_div, best_sel); 1231 } 1232 1233 if (best_rate) { 1234 rk_clrsetreg(&cru->clksel_con[conid], 1235 mask, 1236 best_sel << sel_shift | 1237 (best_div - 1) << div_shift); 1238 } else { 1239 printf("do not support this vop freq %lu\n", rate); 1240 return -EINVAL; 1241 } 1242 } 1243 return rk3576_dclk_vop_get_clk(priv, clk_id); 1244 } 1245 1246 static ulong rk3576_clk_csihost_get_clk(struct rk3576_clk_priv *priv, ulong clk_id) 1247 { 1248 struct rk3576_cru *cru = priv->cru; 1249 u32 div, sel, con, parent; 1250 1251 switch (clk_id) { 1252 case CLK_DSIHOST0: 1253 con = readl(&cru->clksel_con[151]); 1254 div = (con & CLK_DSIHOST0_DIV_MASK) >> CLK_DSIHOST0_DIV_SHIFT; 1255 sel = (con & CLK_DSIHOST0_SEL_MASK) >> CLK_DSIHOST0_SEL_SHIFT; 1256 break; 1257 default: 1258 return -ENOENT; 1259 } 1260 1261 if (sel == CLK_DSIHOST0_SEL_VPLL) 1262 parent = priv->vpll_hz; 1263 else if (sel == CLK_DSIHOST0_SEL_BPLL) 1264 parent = priv->bpll_hz / 4; 1265 else if (sel == CLK_DSIHOST0_SEL_LPLL) 1266 parent = priv->lpll_hz / 2; 1267 else if (sel == CLK_DSIHOST0_SEL_GPLL) 1268 parent = priv->gpll_hz; 1269 else if (sel == CLK_DSIHOST0_SEL_SPLL) 1270 parent = priv->spll_hz; 1271 else 1272 parent = priv->cpll_hz; 1273 1274 return DIV_TO_RATE(parent, div); 1275 } 1276 1277 static ulong rk3576_clk_csihost_set_clk(struct rk3576_clk_priv *priv, 1278 ulong clk_id, ulong rate) 1279 { 1280 struct rk3576_cru *cru = priv->cru; 1281 ulong pll_rate, now, best_rate = 0; 1282 u32 i, con, div, best_div = 0, best_sel = 0; 1283 u32 mask, div_shift, sel_shift; 1284 1285 switch (clk_id) { 1286 case CLK_DSIHOST0: 1287 con = 151; 1288 mask = CLK_DSIHOST0_SEL_MASK | CLK_DSIHOST0_DIV_MASK; 1289 div_shift = CLK_DSIHOST0_DIV_SHIFT; 1290 sel_shift = CLK_DSIHOST0_SEL_SHIFT; 1291 break; 1292 default: 1293 return -ENOENT; 1294 } 1295 for (i = 0; i <= CLK_DSIHOST0_SEL_LPLL; i++) { 1296 switch (i) { 1297 case CLK_DSIHOST0_SEL_GPLL: 1298 pll_rate = priv->gpll_hz; 1299 break; 1300 case CLK_DSIHOST0_SEL_CPLL: 1301 pll_rate = priv->cpll_hz; 1302 break; 1303 case CLK_DSIHOST0_SEL_BPLL: 1304 pll_rate = 0; 1305 break; 1306 case CLK_DSIHOST0_SEL_LPLL: 1307 pll_rate = 0; 1308 break; 1309 case CLK_DSIHOST0_SEL_VPLL: 1310 pll_rate = 0; 1311 break; 1312 case CLK_DSIHOST0_SEL_SPLL: 1313 pll_rate = priv->spll_hz; 1314 break; 1315 default: 1316 printf("do not support this vop pll sel\n"); 1317 return -EINVAL; 1318 } 1319 1320 div = DIV_ROUND_UP(pll_rate, rate); 1321 if (div > 255) 1322 continue; 1323 now = pll_rate / div; 1324 if (abs(rate - now) < abs(rate - best_rate)) { 1325 best_rate = now; 1326 best_div = div; 1327 best_sel = i; 1328 } 1329 debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n", 1330 pll_rate, best_rate, best_div, best_sel); 1331 } 1332 if (best_rate) { 1333 rk_clrsetreg(&cru->clksel_con[con], 1334 mask, 1335 best_sel << sel_shift | 1336 (best_div - 1) << div_shift); 1337 } else { 1338 printf("do not support this vop freq %lu\n", rate); 1339 return -EINVAL; 1340 } 1341 return rk3576_clk_csihost_get_clk(priv, clk_id); 1342 } 1343 1344 static ulong rk3576_dclk_ebc_get_clk(struct rk3576_clk_priv *priv, ulong clk_id) 1345 { 1346 struct rk3576_cru *cru = priv->cru; 1347 u32 div, sel, con, parent; 1348 unsigned long m = 0, n = 0; 1349 1350 switch (clk_id) { 1351 case DCLK_EBC: 1352 con = readl(&cru->clksel_con[123]); 1353 div = (con & DCLK_EBC_DIV_MASK) >> DCLK_EBC_DIV_SHIFT; 1354 sel = (con & DCLK_EBC_SEL_MASK) >> DCLK_EBC_SEL_SHIFT; 1355 if (sel == DCLK_EBC_SEL_CPLL) 1356 parent = priv->cpll_hz; 1357 else if (sel == DCLK_EBC_SEL_VPLL) 1358 parent = priv->vpll_hz; 1359 else if (sel == DCLK_EBC_SEL_AUPLL) 1360 parent = priv->aupll_hz; 1361 else if (sel == DCLK_EBC_SEL_LPLL) 1362 parent = priv->lpll_hz / 2; 1363 else if (sel == DCLK_EBC_SEL_GPLL) 1364 parent = priv->gpll_hz; 1365 else if (sel == DCLK_EBC_SEL_FRAC_SRC) 1366 parent = rk3576_dclk_ebc_get_clk(priv, DCLK_EBC_FRAC_SRC); 1367 else 1368 parent = OSC_HZ; 1369 return DIV_TO_RATE(parent, div); 1370 case DCLK_EBC_FRAC_SRC: 1371 con = readl(&cru->clksel_con[123]); 1372 div = readl(&cru->clksel_con[122]); 1373 sel = (con & DCLK_EBC_FRAC_SRC_SEL_MASK) >> DCLK_EBC_FRAC_SRC_SEL_SHIFT; 1374 if (sel == DCLK_EBC_FRAC_SRC_SEL_GPLL) 1375 parent = priv->gpll_hz; 1376 else if (sel == DCLK_EBC_FRAC_SRC_SEL_CPLL) 1377 parent = priv->cpll_hz; 1378 else if (sel == DCLK_EBC_FRAC_SRC_SEL_VPLL) 1379 parent = priv->vpll_hz; 1380 else if (sel == DCLK_EBC_FRAC_SRC_SEL_AUPLL) 1381 parent = priv->aupll_hz; 1382 else 1383 parent = OSC_HZ; 1384 1385 n = div & CLK_UART_FRAC_NUMERATOR_MASK; 1386 n >>= CLK_UART_FRAC_NUMERATOR_SHIFT; 1387 m = div & CLK_UART_FRAC_DENOMINATOR_MASK; 1388 m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT; 1389 return parent * n / m; 1390 default: 1391 return -ENOENT; 1392 } 1393 } 1394 1395 static ulong rk3576_dclk_ebc_set_clk(struct rk3576_clk_priv *priv, 1396 ulong clk_id, ulong rate) 1397 { 1398 struct rk3576_cru *cru = priv->cru; 1399 u32 div, sel; 1400 unsigned long m = 0, n = 0, val; 1401 1402 switch (clk_id) { 1403 case DCLK_EBC: 1404 if (!(priv->gpll_hz % rate)) { 1405 sel = DCLK_EBC_SEL_GPLL; 1406 div = priv->gpll_hz / rate; 1407 } else if (!(priv->cpll_hz % rate)) { 1408 sel = DCLK_EBC_SEL_CPLL; 1409 div = priv->cpll_hz / rate; 1410 } else if (!(priv->aupll_hz % rate)) { 1411 sel = DCLK_EBC_SEL_AUPLL; 1412 div = priv->aupll_hz / rate; 1413 } else if (!(priv->vpll_hz % rate)) { 1414 sel = DCLK_EBC_SEL_VPLL; 1415 div = priv->vpll_hz / rate; 1416 } else if (!(OSC_HZ % rate)) { 1417 sel = DCLK_EBC_SEL_OSC; 1418 div = OSC_HZ / rate; 1419 } else { 1420 sel = DCLK_EBC_SEL_FRAC_SRC; 1421 rk3576_dclk_ebc_set_clk(priv, DCLK_EBC_FRAC_SRC, rate); 1422 div = rk3576_dclk_ebc_get_clk(priv, DCLK_EBC_FRAC_SRC) / rate; 1423 } 1424 rk_clrsetreg(&cru->clksel_con[123], 1425 DCLK_EBC_SEL_MASK | DCLK_EBC_DIV_MASK, 1426 (sel << DCLK_EBC_SEL_SHIFT) | 1427 (div - 1) << DCLK_EBC_DIV_SHIFT); 1428 break; 1429 case DCLK_EBC_FRAC_SRC: 1430 sel = DCLK_EBC_FRAC_SRC_SEL_GPLL; 1431 div = 1; 1432 rational_best_approximation(rate, priv->gpll_hz, 1433 GENMASK(16 - 1, 0), 1434 GENMASK(16 - 1, 0), 1435 &m, &n); 1436 1437 if (m < 4 && m != 0) { 1438 if (n % 2 == 0) 1439 val = 1; 1440 else 1441 val = DIV_ROUND_UP(4, m); 1442 1443 n *= val; 1444 m *= val; 1445 if (n > 0xffff) { 1446 n = 0xffff; 1447 } 1448 } 1449 1450 rk_clrsetreg(&cru->clksel_con[123], 1451 DCLK_EBC_FRAC_SRC_SEL_MASK, 1452 (sel << DCLK_EBC_FRAC_SRC_SEL_SHIFT)); 1453 if (m && n) { 1454 val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n; 1455 writel(val, &cru->clksel_con[122]); 1456 } 1457 break; 1458 default: 1459 return -ENOENT; 1460 } 1461 return rk3576_dclk_ebc_get_clk(priv, clk_id); 1462 } 1463 1464 static ulong rk3576_gmac_get_clk(struct rk3576_clk_priv *priv, ulong clk_id) 1465 { 1466 struct rk3576_cru *cru = priv->cru; 1467 u32 con, div, src, p_rate; 1468 1469 switch (clk_id) { 1470 case CLK_GMAC0_PTP_REF_SRC: 1471 case CLK_GMAC0_PTP_REF: 1472 con = readl(&cru->clksel_con[105]); 1473 div = (con & CLK_GMAC0_PTP_DIV_MASK) >> CLK_GMAC0_PTP_DIV_SHIFT; 1474 src = (con & CLK_GMAC0_PTP_SEL_MASK) >> CLK_GMAC0_PTP_SEL_SHIFT; 1475 if (src == CLK_GMAC0_PTP_SEL_GPLL) 1476 p_rate = priv->gpll_hz; 1477 else if (src == CLK_GMAC0_PTP_SEL_CPLL) 1478 p_rate = priv->cpll_hz; 1479 else 1480 p_rate = GMAC0_PTP_REFCLK_IN; 1481 return DIV_TO_RATE(p_rate, div); 1482 case CLK_GMAC1_PTP_REF_SRC: 1483 case CLK_GMAC1_PTP_REF: 1484 con = readl(&cru->clksel_con[104]); 1485 div = (con & CLK_GMAC1_PTP_DIV_MASK) >> CLK_GMAC0_PTP_DIV_SHIFT; 1486 src = (con & CLK_GMAC1_PTP_SEL_MASK) >> CLK_GMAC1_PTP_SEL_SHIFT; 1487 if (src == CLK_GMAC1_PTP_SEL_GPLL) 1488 p_rate = priv->gpll_hz; 1489 else if (src == CLK_GMAC1_PTP_SEL_CPLL) 1490 p_rate = priv->cpll_hz; 1491 else 1492 p_rate = GMAC1_PTP_REFCLK_IN; 1493 return DIV_TO_RATE(p_rate, div); 1494 case CLK_GMAC0_125M_SRC: 1495 con = readl(&cru->clksel_con[30]); 1496 div = (con & CLK_GMAC0_125M_DIV_MASK) >> CLK_GMAC0_125M_DIV_SHIFT; 1497 return DIV_TO_RATE(priv->cpll_hz, div); 1498 case CLK_GMAC1_125M_SRC: 1499 con = readl(&cru->clksel_con[31]); 1500 div = (con & CLK_GMAC1_125M_DIV_MASK) >> CLK_GMAC1_125M_DIV_SHIFT; 1501 return DIV_TO_RATE(priv->cpll_hz, div); 1502 default: 1503 return -ENOENT; 1504 } 1505 } 1506 1507 static ulong rk3576_gmac_set_clk(struct rk3576_clk_priv *priv, 1508 ulong clk_id, ulong rate) 1509 { 1510 struct rk3576_cru *cru = priv->cru; 1511 int div, src; 1512 1513 div = DIV_ROUND_UP(priv->cpll_hz, rate); 1514 1515 switch (clk_id) { 1516 case CLK_GMAC0_PTP_REF_SRC: 1517 case CLK_GMAC0_PTP_REF: 1518 if (rate == GMAC0_PTP_REFCLK_IN) { 1519 src = CLK_GMAC0_PTP_SEL_REFIN; 1520 div = 1; 1521 } else if (!(priv->gpll_hz % rate)) { 1522 src = CLK_GMAC0_PTP_SEL_GPLL; 1523 div = priv->gpll_hz / rate; 1524 } else { 1525 src = CLK_GMAC0_PTP_SEL_CPLL; 1526 div = priv->cpll_hz / rate; 1527 } 1528 rk_clrsetreg(&cru->clksel_con[105], 1529 CLK_GMAC0_PTP_DIV_MASK | CLK_GMAC0_PTP_SEL_MASK, 1530 src << CLK_GMAC0_PTP_SEL_SHIFT | 1531 (div - 1) << CLK_GMAC0_PTP_DIV_SHIFT); 1532 break; 1533 case CLK_GMAC1_PTP_REF_SRC: 1534 case CLK_GMAC1_PTP_REF: 1535 if (rate == GMAC1_PTP_REFCLK_IN) { 1536 src = CLK_GMAC1_PTP_SEL_REFIN; 1537 div = 1; 1538 } else if (!(priv->gpll_hz % rate)) { 1539 src = CLK_GMAC1_PTP_SEL_GPLL; 1540 div = priv->gpll_hz / rate; 1541 } else { 1542 src = CLK_GMAC1_PTP_SEL_CPLL; 1543 div = priv->cpll_hz / rate; 1544 } 1545 rk_clrsetreg(&cru->clksel_con[104], 1546 CLK_GMAC1_PTP_DIV_MASK | CLK_GMAC1_PTP_SEL_MASK, 1547 src << CLK_GMAC1_PTP_SEL_SHIFT | 1548 (div - 1) << CLK_GMAC1_PTP_DIV_SHIFT); 1549 break; 1550 1551 case CLK_GMAC0_125M_SRC: 1552 rk_clrsetreg(&cru->clksel_con[30], 1553 CLK_GMAC0_125M_DIV_MASK, 1554 (div - 1) << CLK_GMAC0_125M_DIV_SHIFT); 1555 break; 1556 case CLK_GMAC1_125M_SRC: 1557 rk_clrsetreg(&cru->clksel_con[31], 1558 CLK_GMAC1_125M_DIV_MASK, 1559 (div - 1) << CLK_GMAC1_125M_DIV_SHIFT); 1560 break; 1561 default: 1562 return -ENOENT; 1563 } 1564 1565 return rk3576_gmac_get_clk(priv, clk_id); 1566 } 1567 1568 static ulong rk3576_uart_frac_get_rate(struct rk3576_clk_priv *priv, ulong clk_id) 1569 { 1570 struct rk3576_cru *cru = priv->cru; 1571 u32 reg, con, fracdiv, p_src, p_rate; 1572 unsigned long m, n; 1573 1574 switch (clk_id) { 1575 case CLK_UART_FRAC_0: 1576 reg = 21; 1577 break; 1578 case CLK_UART_FRAC_1: 1579 reg = 23; 1580 break; 1581 case CLK_UART_FRAC_2: 1582 reg = 25; 1583 break; 1584 default: 1585 return -ENOENT; 1586 } 1587 con = readl(&cru->clksel_con[reg + 1]); 1588 p_src = (con & CLK_UART_SRC_SEL_MASK) >> CLK_UART_SRC_SEL_SHIFT; 1589 if (p_src == CLK_UART_SRC_SEL_GPLL) 1590 p_rate = priv->gpll_hz; 1591 else if (p_src == CLK_UART_SRC_SEL_CPLL) 1592 p_rate = priv->cpll_hz; 1593 else if (p_src == CLK_UART_SRC_SEL_AUPLL) 1594 p_rate = priv->aupll_hz; 1595 else 1596 p_rate = OSC_HZ; 1597 1598 fracdiv = readl(&cru->clksel_con[reg]); 1599 n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK; 1600 n >>= CLK_UART_FRAC_NUMERATOR_SHIFT; 1601 m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK; 1602 m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT; 1603 return p_rate * n / m; 1604 } 1605 1606 static ulong rk3576_uart_frac_set_rate(struct rk3576_clk_priv *priv, 1607 ulong clk_id, ulong rate) 1608 { 1609 struct rk3576_cru *cru = priv->cru; 1610 u32 reg, clk_src, p_rate; 1611 unsigned long m = 0, n = 0, val; 1612 1613 if (priv->cpll_hz % rate == 0) { 1614 clk_src = CLK_UART_SRC_SEL_CPLL; 1615 p_rate = priv->cpll_hz; 1616 } else if (rate == OSC_HZ) { 1617 clk_src = CLK_UART_SRC_SEL_OSC; 1618 p_rate = OSC_HZ; 1619 } else { 1620 clk_src = CLK_UART_SRC_SEL_GPLL; 1621 p_rate = priv->cpll_hz; 1622 } 1623 rational_best_approximation(rate, p_rate, 1624 GENMASK(16 - 1, 0), 1625 GENMASK(16 - 1, 0), 1626 &m, &n); 1627 1628 if (m < 4 && m != 0) { 1629 if (n % 2 == 0) 1630 val = 1; 1631 else 1632 val = DIV_ROUND_UP(4, m); 1633 1634 n *= val; 1635 m *= val; 1636 if (n > 0xffff) { 1637 n = 0xffff; 1638 } 1639 } 1640 1641 1642 switch (clk_id) { 1643 case CLK_UART_FRAC_0: 1644 reg = 21; 1645 break; 1646 case CLK_UART_FRAC_1: 1647 reg = 23; 1648 break; 1649 case CLK_UART_FRAC_2: 1650 reg = 25; 1651 break; 1652 default: 1653 return -ENOENT; 1654 } 1655 rk_clrsetreg(&cru->clksel_con[reg +1], 1656 CLK_UART_SRC_SEL_MASK, 1657 (clk_src << CLK_UART_SRC_SEL_SHIFT)); 1658 if (m && n) { 1659 val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n; 1660 writel(val, &cru->clksel_con[reg]); 1661 } 1662 1663 return rk3576_uart_frac_get_rate(priv, clk_id); 1664 } 1665 1666 1667 static ulong rk3576_uart_get_rate(struct rk3576_clk_priv *priv, ulong clk_id) 1668 { 1669 struct rk3576_cru *cru = priv->cru; 1670 u32 con, div, src, p_rate; 1671 1672 switch (clk_id) { 1673 case SCLK_UART0: 1674 con = readl(&cru->clksel_con[60]); 1675 break; 1676 case SCLK_UART1: 1677 con = readl(&cru->pmuclksel_con[8]); 1678 src = (con & CLK_UART1_SEL_MASK) >> CLK_UART1_SEL_SHIFT; 1679 if (src == CLK_UART1_SEL_OSC) 1680 return OSC_HZ; 1681 con = readl(&cru->clksel_con[27]); 1682 break; 1683 case SCLK_UART2: 1684 con = readl(&cru->clksel_con[61]); 1685 break; 1686 case SCLK_UART3: 1687 con = readl(&cru->clksel_con[62]); 1688 break; 1689 case SCLK_UART4: 1690 con = readl(&cru->clksel_con[63]); 1691 break; 1692 case SCLK_UART5: 1693 con = readl(&cru->clksel_con[64]); 1694 break; 1695 case SCLK_UART6: 1696 con = readl(&cru->clksel_con[65]); 1697 break; 1698 case SCLK_UART7: 1699 con = readl(&cru->clksel_con[66]); 1700 break; 1701 case SCLK_UART8: 1702 con = readl(&cru->clksel_con[67]); 1703 break; 1704 case SCLK_UART9: 1705 con = readl(&cru->clksel_con[68]); 1706 break; 1707 case SCLK_UART10: 1708 con = readl(&cru->clksel_con[69]); 1709 break; 1710 case SCLK_UART11: 1711 con = readl(&cru->clksel_con[70]); 1712 break; 1713 default: 1714 return -ENOENT; 1715 } 1716 if (clk_id == SCLK_UART1) { 1717 src = (con & CLK_UART1_SRC_SEL_SHIFT) >> CLK_UART1_SRC_SEL_SHIFT; 1718 div = (con & CLK_UART1_SRC_DIV_MASK) >> CLK_UART1_SRC_DIV_SHIFT; 1719 } else { 1720 src = (con & CLK_UART_SEL_MASK) >> CLK_UART_SEL_SHIFT; 1721 div = (con & CLK_UART_DIV_MASK) >> CLK_UART_DIV_SHIFT; 1722 } 1723 if (src == CLK_UART_SEL_GPLL) 1724 p_rate = priv->gpll_hz; 1725 else if (src == CLK_UART_SEL_CPLL) 1726 p_rate = priv->cpll_hz; 1727 else if (src == CLK_UART_SEL_AUPLL) 1728 p_rate = priv->aupll_hz; 1729 else if (src == CLK_UART_SEL_FRAC0) 1730 p_rate = rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_0); 1731 else if (src == CLK_UART_SEL_FRAC1) 1732 p_rate = rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_1); 1733 else if (src == CLK_UART_SEL_FRAC2) 1734 p_rate = rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_2); 1735 else 1736 p_rate = OSC_HZ; 1737 1738 return DIV_TO_RATE(p_rate, div); 1739 } 1740 1741 static ulong rk3576_uart_set_rate(struct rk3576_clk_priv *priv, 1742 ulong clk_id, ulong rate) 1743 { 1744 struct rk3576_cru *cru = priv->cru; 1745 u32 reg, clk_src = 0, div = 0; 1746 1747 if (!(priv->gpll_hz % rate)) { 1748 clk_src = CLK_UART_SEL_GPLL; 1749 div = DIV_ROUND_UP(priv->gpll_hz, rate); 1750 } else if (!(priv->cpll_hz % rate)) { 1751 clk_src = CLK_UART_SEL_CPLL; 1752 div = DIV_ROUND_UP(priv->gpll_hz, rate); 1753 } else if (!(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_0) % rate)) { 1754 clk_src = CLK_UART_SEL_FRAC0; 1755 div = DIV_ROUND_UP(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_0), rate); 1756 } else if (!(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_1) % rate)) { 1757 clk_src = CLK_UART_SEL_FRAC1; 1758 div = DIV_ROUND_UP(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_1), rate); 1759 } else if (!(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_2) % rate)) { 1760 clk_src = CLK_UART_SEL_FRAC2; 1761 div = DIV_ROUND_UP(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_2), rate); 1762 } else if (!(OSC_HZ % rate)) { 1763 clk_src = CLK_UART_SEL_OSC; 1764 div = DIV_ROUND_UP(OSC_HZ, rate); 1765 } 1766 1767 switch (clk_id) { 1768 case SCLK_UART0: 1769 reg = 60; 1770 break; 1771 case SCLK_UART1: 1772 if (rate == OSC_HZ) { 1773 rk_clrsetreg(&cru->pmuclksel_con[8], 1774 CLK_UART1_SEL_MASK, 1775 (CLK_UART1_SEL_OSC << CLK_UART1_SEL_SHIFT)); 1776 return 0; 1777 } else { 1778 rk_clrsetreg(&cru->clksel_con[27], 1779 CLK_UART1_SRC_SEL_MASK | 1780 CLK_UART1_SRC_DIV_MASK, 1781 (clk_src << CLK_UART1_SRC_SEL_SHIFT) | 1782 ((div - 1) << CLK_UART1_SRC_DIV_SHIFT)); 1783 rk_clrsetreg(&cru->pmuclksel_con[8], 1784 CLK_UART1_SEL_MASK, 1785 (CLK_UART1_SEL_TOP << CLK_UART1_SEL_SHIFT)); 1786 return 0; 1787 } 1788 break; 1789 case SCLK_UART2: 1790 reg = 61; 1791 break; 1792 case SCLK_UART3: 1793 reg = 62; 1794 break; 1795 case SCLK_UART4: 1796 reg = 63; 1797 break; 1798 case SCLK_UART5: 1799 reg = 64; 1800 break; 1801 case SCLK_UART6: 1802 reg = 65; 1803 break; 1804 case SCLK_UART7: 1805 reg = 66; 1806 break; 1807 case SCLK_UART8: 1808 reg = 67; 1809 break; 1810 case SCLK_UART9: 1811 reg = 68; 1812 break; 1813 case SCLK_UART10: 1814 reg = 69; 1815 break; 1816 case SCLK_UART11: 1817 reg = 70; 1818 break; 1819 default: 1820 return -ENOENT; 1821 } 1822 rk_clrsetreg(&cru->clksel_con[reg], 1823 CLK_UART_SEL_MASK | 1824 CLK_UART_DIV_MASK, 1825 (clk_src << CLK_UART_SEL_SHIFT) | 1826 ((div - 1) << CLK_UART_DIV_SHIFT)); 1827 1828 return rk3576_uart_get_rate(priv, clk_id); 1829 } 1830 #endif 1831 1832 static ulong rk3576_ufs_ref_get_rate(struct rk3576_clk_priv *priv, ulong clk_id) 1833 { 1834 struct rk3576_cru *cru = priv->cru; 1835 u32 src, div; 1836 1837 src = readl(&cru->pmuclksel_con[3]) & 0x3; 1838 div= readl(&cru->pmuclksel_con[1]) & 0xff; 1839 if (src == 0) 1840 return OSC_HZ; 1841 else if (src == 2) 1842 return priv->ppll_hz / (div + 1); 1843 else 1844 return 26000000; 1845 1846 } 1847 1848 static ulong rk3576_clk_get_rate(struct clk *clk) 1849 { 1850 struct rk3576_clk_priv *priv = dev_get_priv(clk->dev); 1851 ulong rate = 0; 1852 1853 if (!priv->gpll_hz) { 1854 printf("%s gpll=%lu\n", __func__, priv->gpll_hz); 1855 return -ENOENT; 1856 } 1857 1858 if (!priv->ppll_hz) { 1859 priv->ppll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[PPLL], 1860 priv->cru, PPLL); 1861 } 1862 1863 switch (clk->id) { 1864 case PLL_LPLL: 1865 rate = rockchip_pll_get_rate(&rk3576_pll_clks[LPLL], priv->cru, 1866 LPLL); 1867 priv->lpll_hz = rate; 1868 break; 1869 case PLL_BPLL: 1870 rate = rockchip_pll_get_rate(&rk3576_pll_clks[BPLL], priv->cru, 1871 BPLL); 1872 priv->bpll_hz = rate; 1873 break; 1874 case PLL_GPLL: 1875 rate = rockchip_pll_get_rate(&rk3576_pll_clks[GPLL], priv->cru, 1876 GPLL); 1877 break; 1878 case PLL_CPLL: 1879 rate = rockchip_pll_get_rate(&rk3576_pll_clks[CPLL], priv->cru, 1880 CPLL); 1881 break; 1882 case PLL_VPLL: 1883 rate = rockchip_pll_get_rate(&rk3576_pll_clks[VPLL], priv->cru, 1884 VPLL); 1885 break; 1886 case PLL_AUPLL: 1887 rate = rockchip_pll_get_rate(&rk3576_pll_clks[AUPLL], priv->cru, 1888 AUPLL); 1889 break; 1890 case PLL_PPLL: 1891 rate = rockchip_pll_get_rate(&rk3576_pll_clks[PPLL], priv->cru, 1892 PPLL) * 2; 1893 break; 1894 case ACLK_BUS_ROOT: 1895 case HCLK_BUS_ROOT: 1896 case PCLK_BUS_ROOT: 1897 rate = rk3576_bus_get_clk(priv, clk->id); 1898 break; 1899 case ACLK_TOP: 1900 case HCLK_TOP: 1901 case PCLK_TOP_ROOT: 1902 case ACLK_TOP_MID: 1903 rate = rk3576_top_get_clk(priv, clk->id); 1904 break; 1905 case CLK_I2C0: 1906 case CLK_I2C1: 1907 case CLK_I2C2: 1908 case CLK_I2C3: 1909 case CLK_I2C4: 1910 case CLK_I2C5: 1911 case CLK_I2C6: 1912 case CLK_I2C7: 1913 case CLK_I2C8: 1914 case CLK_I2C9: 1915 rate = rk3576_i2c_get_clk(priv, clk->id); 1916 break; 1917 case CLK_SPI0: 1918 case CLK_SPI1: 1919 case CLK_SPI2: 1920 case CLK_SPI3: 1921 case CLK_SPI4: 1922 rate = rk3576_spi_get_clk(priv, clk->id); 1923 break; 1924 case CLK_PWM1: 1925 case CLK_PWM2: 1926 case CLK_PMU1PWM: 1927 rate = rk3576_pwm_get_clk(priv, clk->id); 1928 break; 1929 case CLK_SARADC: 1930 case CLK_TSADC: 1931 rate = rk3576_adc_get_clk(priv, clk->id); 1932 break; 1933 case CCLK_SRC_SDIO: 1934 case CCLK_SRC_SDMMC0: 1935 case CCLK_SRC_EMMC: 1936 case BCLK_EMMC: 1937 case SCLK_FSPI_X2: 1938 case SCLK_FSPI1_X2: 1939 rate = rk3576_mmc_get_clk(priv, clk->id); 1940 break; 1941 case TCLK_WDT0: 1942 rate = OSC_HZ; 1943 break; 1944 #ifndef CONFIG_SPL_BUILD 1945 case ACLK_VOP_ROOT: 1946 case ACLK_VOP: 1947 case ACLK_VO0_ROOT: 1948 case ACLK_VO1_ROOT: 1949 case HCLK_VOP_ROOT: 1950 case PCLK_VOP_ROOT: 1951 rate = rk3576_aclk_vop_get_clk(priv, clk->id); 1952 break; 1953 case DCLK_VP0: 1954 case DCLK_VP0_SRC: 1955 case DCLK_VP1: 1956 case DCLK_VP1_SRC: 1957 case DCLK_VP2: 1958 case DCLK_VP2_SRC: 1959 rate = rk3576_dclk_vop_get_clk(priv, clk->id); 1960 break; 1961 case CLK_GMAC0_PTP_REF_SRC: 1962 case CLK_GMAC1_PTP_REF_SRC: 1963 case CLK_GMAC0_PTP_REF: 1964 case CLK_GMAC1_PTP_REF: 1965 case CLK_GMAC0_125M_SRC: 1966 case CLK_GMAC1_125M_SRC: 1967 rate = rk3576_gmac_get_clk(priv, clk->id); 1968 break; 1969 case CLK_UART_FRAC_0: 1970 case CLK_UART_FRAC_1: 1971 case CLK_UART_FRAC_2: 1972 rate = rk3576_uart_frac_get_rate(priv, clk->id); 1973 break; 1974 case SCLK_UART0: 1975 case SCLK_UART1: 1976 case SCLK_UART2: 1977 case SCLK_UART3: 1978 case SCLK_UART4: 1979 case SCLK_UART5: 1980 case SCLK_UART6: 1981 case SCLK_UART7: 1982 case SCLK_UART8: 1983 case SCLK_UART9: 1984 case SCLK_UART10: 1985 case SCLK_UART11: 1986 rate = rk3576_uart_get_rate(priv, clk->id); 1987 break; 1988 case CLK_DSIHOST0: 1989 rate = rk3576_clk_csihost_get_clk(priv, clk->id); 1990 break; 1991 case DCLK_EBC: 1992 case DCLK_EBC_FRAC_SRC: 1993 rate = rk3576_dclk_ebc_get_clk(priv, clk->id); 1994 break; 1995 #endif 1996 case CLK_REF_UFS_CLKOUT: 1997 case CLK_REF_OSC_MPHY: 1998 rate = rk3576_ufs_ref_get_rate(priv, clk->id); 1999 break; 2000 2001 default: 2002 return -ENOENT; 2003 } 2004 2005 return rate; 2006 }; 2007 2008 static ulong rk3576_clk_set_rate(struct clk *clk, ulong rate) 2009 { 2010 struct rk3576_clk_priv *priv = dev_get_priv(clk->dev); 2011 ulong ret = 0; 2012 2013 if (!priv->ppll_hz) { 2014 priv->ppll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[PPLL], 2015 priv->cru, PPLL); 2016 } 2017 if (!priv->aupll_hz) { 2018 priv->aupll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[AUPLL], 2019 priv->cru, AUPLL); 2020 } 2021 2022 switch (clk->id) { 2023 case PLL_CPLL: 2024 ret = rockchip_pll_set_rate(&rk3576_pll_clks[CPLL], priv->cru, 2025 CPLL, rate); 2026 priv->cpll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[CPLL], 2027 priv->cru, CPLL); 2028 break; 2029 case PLL_GPLL: 2030 ret = rockchip_pll_set_rate(&rk3576_pll_clks[GPLL], priv->cru, 2031 GPLL, rate); 2032 priv->gpll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[GPLL], 2033 priv->cru, GPLL); 2034 break; 2035 case PLL_VPLL: 2036 ret = rockchip_pll_set_rate(&rk3576_pll_clks[VPLL], priv->cru, 2037 VPLL, rate); 2038 priv->vpll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[VPLL], 2039 priv->cru, VPLL); 2040 break; 2041 case PLL_AUPLL: 2042 ret = rockchip_pll_set_rate(&rk3576_pll_clks[AUPLL], priv->cru, 2043 AUPLL, rate); 2044 priv->aupll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[AUPLL], 2045 priv->cru, AUPLL); 2046 break; 2047 case PLL_PPLL: 2048 ret = rockchip_pll_set_rate(&rk3576_pll_clks[PPLL], priv->cru, 2049 PPLL, rate); 2050 priv->ppll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[PPLL], 2051 priv->cru, PPLL) * 2; 2052 break; 2053 case ACLK_BUS_ROOT: 2054 case HCLK_BUS_ROOT: 2055 case PCLK_BUS_ROOT: 2056 ret = rk3576_bus_set_clk(priv, clk->id, rate); 2057 break; 2058 case ACLK_TOP: 2059 case HCLK_TOP: 2060 case PCLK_TOP_ROOT: 2061 case ACLK_TOP_MID: 2062 ret = rk3576_top_set_clk(priv, clk->id, rate); 2063 break; 2064 case CLK_I2C0: 2065 case CLK_I2C1: 2066 case CLK_I2C2: 2067 case CLK_I2C3: 2068 case CLK_I2C4: 2069 case CLK_I2C5: 2070 case CLK_I2C6: 2071 case CLK_I2C7: 2072 case CLK_I2C8: 2073 case CLK_I2C9: 2074 ret = rk3576_i2c_set_clk(priv, clk->id, rate); 2075 break; 2076 case CLK_SPI0: 2077 case CLK_SPI1: 2078 case CLK_SPI2: 2079 case CLK_SPI3: 2080 case CLK_SPI4: 2081 ret = rk3576_spi_set_clk(priv, clk->id, rate); 2082 break; 2083 case CLK_PWM1: 2084 case CLK_PWM2: 2085 case CLK_PMU1PWM: 2086 ret = rk3576_pwm_set_clk(priv, clk->id, rate); 2087 break; 2088 case CLK_SARADC: 2089 case CLK_TSADC: 2090 ret = rk3576_adc_set_clk(priv, clk->id, rate); 2091 break; 2092 case CCLK_SRC_SDIO: 2093 case CCLK_SRC_SDMMC0: 2094 case CCLK_SRC_EMMC: 2095 case BCLK_EMMC: 2096 case SCLK_FSPI_X2: 2097 case SCLK_FSPI1_X2: 2098 ret = rk3576_mmc_set_clk(priv, clk->id, rate); 2099 break; 2100 case TCLK_WDT0: 2101 ret = OSC_HZ; 2102 break; 2103 #ifndef CONFIG_SPL_BUILD 2104 case ACLK_VOP_ROOT: 2105 case ACLK_VOP: 2106 case ACLK_VO0_ROOT: 2107 case ACLK_VO1_ROOT: 2108 case HCLK_VOP_ROOT: 2109 case PCLK_VOP_ROOT: 2110 ret = rk3576_aclk_vop_set_clk(priv, clk->id, rate); 2111 break; 2112 case DCLK_VP0: 2113 case DCLK_VP0_SRC: 2114 case DCLK_VP1: 2115 case DCLK_VP1_SRC: 2116 case DCLK_VP2: 2117 case DCLK_VP2_SRC: 2118 ret = rk3576_dclk_vop_set_clk(priv, clk->id, rate); 2119 break; 2120 case CLK_GMAC0_PTP_REF_SRC: 2121 case CLK_GMAC1_PTP_REF_SRC: 2122 case CLK_GMAC0_PTP_REF: 2123 case CLK_GMAC1_PTP_REF: 2124 case CLK_GMAC0_125M_SRC: 2125 case CLK_GMAC1_125M_SRC: 2126 ret = rk3576_gmac_set_clk(priv, clk->id, rate); 2127 break; 2128 case CLK_UART_FRAC_0: 2129 case CLK_UART_FRAC_1: 2130 case CLK_UART_FRAC_2: 2131 ret = rk3576_uart_frac_set_rate(priv, clk->id, rate); 2132 break; 2133 case SCLK_UART0: 2134 case SCLK_UART1: 2135 case SCLK_UART2: 2136 case SCLK_UART3: 2137 case SCLK_UART4: 2138 case SCLK_UART5: 2139 case SCLK_UART6: 2140 case SCLK_UART7: 2141 case SCLK_UART8: 2142 case SCLK_UART9: 2143 case SCLK_UART10: 2144 case SCLK_UART11: 2145 ret = rk3576_uart_set_rate(priv, clk->id, rate); 2146 break; 2147 case CLK_DSIHOST0: 2148 ret = rk3576_clk_csihost_set_clk(priv, clk->id, rate); 2149 break; 2150 case DCLK_EBC: 2151 case DCLK_EBC_FRAC_SRC: 2152 ret = rk3576_dclk_ebc_set_clk(priv, clk->id, rate); 2153 break; 2154 #endif 2155 default: 2156 return -ENOENT; 2157 } 2158 2159 return ret; 2160 }; 2161 2162 #if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA)) 2163 static int __maybe_unused rk3576_dclk_vop_set_parent(struct clk *clk, 2164 struct clk *parent) 2165 { 2166 struct rk3576_clk_priv *priv = dev_get_priv(clk->dev); 2167 struct rk3576_cru *cru = priv->cru; 2168 u32 sel; 2169 const char *clock_dev_name = parent->dev->name; 2170 2171 if (parent->id == PLL_VPLL) 2172 sel = 2; 2173 else if (parent->id == PLL_GPLL) 2174 sel = 0; 2175 else if (parent->id == PLL_CPLL) 2176 sel = 1; 2177 else if (parent->id == PLL_BPLL) 2178 sel = 3; 2179 else 2180 sel = 4; 2181 2182 switch (clk->id) { 2183 case DCLK_VP0_SRC: 2184 rk_clrsetreg(&cru->clksel_con[145], DCLK0_VOP_SRC_SEL_MASK, 2185 sel << DCLK0_VOP_SRC_SEL_SHIFT); 2186 break; 2187 case DCLK_VP1_SRC: 2188 rk_clrsetreg(&cru->clksel_con[146], DCLK0_VOP_SRC_SEL_MASK, 2189 sel << DCLK0_VOP_SRC_SEL_SHIFT); 2190 break; 2191 case DCLK_VP2_SRC: 2192 rk_clrsetreg(&cru->clksel_con[147], DCLK0_VOP_SRC_SEL_MASK, 2193 sel << DCLK0_VOP_SRC_SEL_SHIFT); 2194 break; 2195 case DCLK_VP0: 2196 if (!strcmp(clock_dev_name, "hdmiphypll_clk0")) 2197 sel = 1; 2198 else 2199 sel = 0; 2200 rk_clrsetreg(&cru->clksel_con[147], DCLK0_VOP_SEL_MASK, 2201 sel << DCLK0_VOP_SEL_SHIFT); 2202 break; 2203 case DCLK_VP1: 2204 if (!strcmp(clock_dev_name, "hdmiphypll_clk0")) 2205 sel = 1; 2206 else 2207 sel = 0; 2208 rk_clrsetreg(&cru->clksel_con[147], DCLK1_VOP_SEL_MASK, 2209 sel << DCLK1_VOP_SEL_SHIFT); 2210 break; 2211 case DCLK_VP2: 2212 if (!strcmp(clock_dev_name, "hdmiphypll_clk0")) 2213 sel = 1; 2214 else 2215 sel = 0; 2216 rk_clrsetreg(&cru->clksel_con[147], DCLK2_VOP_SEL_MASK, 2217 sel << DCLK2_VOP_SEL_SHIFT); 2218 break; 2219 default: 2220 return -EINVAL; 2221 } 2222 return 0; 2223 } 2224 2225 static int __maybe_unused rk3576_ufs_ref_set_parent(struct clk *clk, 2226 struct clk *parent) 2227 { 2228 struct rk3576_clk_priv *priv = dev_get_priv(clk->dev); 2229 struct rk3576_cru *cru = priv->cru; 2230 u32 sel; 2231 const char *clock_dev_name = parent->dev->name; 2232 2233 if (parent->id == CLK_REF_MPHY_26M) 2234 sel = 2; 2235 else if (!strcmp(clock_dev_name, "xin24m")) 2236 sel = 0; 2237 else 2238 sel = 1; 2239 2240 rk_clrsetreg(&cru->pmuclksel_con[3], 0x3, sel << 0); 2241 return 0; 2242 } 2243 2244 static int rk3576_clk_set_parent(struct clk *clk, struct clk *parent) 2245 { 2246 switch (clk->id) { 2247 case DCLK_VP0_SRC: 2248 case DCLK_VP1_SRC: 2249 case DCLK_VP2_SRC: 2250 case DCLK_VP0: 2251 case DCLK_VP1: 2252 case DCLK_VP2: 2253 return rk3576_dclk_vop_set_parent(clk, parent); 2254 case CLK_REF_OSC_MPHY: 2255 return rk3576_ufs_ref_set_parent(clk, parent); 2256 2257 default: 2258 return -ENOENT; 2259 } 2260 2261 return 0; 2262 } 2263 #endif 2264 2265 static struct clk_ops rk3576_clk_ops = { 2266 .get_rate = rk3576_clk_get_rate, 2267 .set_rate = rk3576_clk_set_rate, 2268 #if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA)) 2269 .set_parent = rk3576_clk_set_parent, 2270 #endif 2271 }; 2272 2273 static void rk3576_clk_init(struct rk3576_clk_priv *priv) 2274 { 2275 int ret; 2276 2277 priv->spll_hz = 702000000; 2278 2279 if (priv->cpll_hz != CPLL_HZ) { 2280 ret = rockchip_pll_set_rate(&rk3576_pll_clks[CPLL], priv->cru, 2281 CPLL, CPLL_HZ); 2282 if (!ret) 2283 priv->cpll_hz = CPLL_HZ; 2284 } 2285 if (priv->gpll_hz != GPLL_HZ) { 2286 ret = rockchip_pll_set_rate(&rk3576_pll_clks[GPLL], priv->cru, 2287 GPLL, GPLL_HZ); 2288 if (!ret) 2289 priv->gpll_hz = GPLL_HZ; 2290 } 2291 } 2292 2293 static int rk3576_clk_probe(struct udevice *dev) 2294 { 2295 struct rk3576_clk_priv *priv = dev_get_priv(dev); 2296 int ret; 2297 #if CONFIG_IS_ENABLED(CLK_SCMI) 2298 struct clk clk; 2299 #endif 2300 2301 priv->sync_kernel = false; 2302 2303 #ifdef CONFIG_SPL_BUILD 2304 /* relase presetn_bigcore_biu/cru/grf */ 2305 writel(0x1c001c00, 0x26010010); 2306 /* set spll to normal mode */ 2307 writel(BITS_WITH_WMASK(2, 0x7U, 6), 2308 RK3576_SCRU_BASE + RK3576_PLL_CON(137)); 2309 writel(BITS_WITH_WMASK(1, 0x3U, 0), 2310 RK3576_SCRU_BASE + RK3576_MODE_CON0); 2311 /* fix ppll\aupll\cpll */ 2312 writel(BITS_WITH_WMASK(2, 0x7U, 6), 2313 RK3576_CRU_BASE + RK3576_PMU_PLL_CON(129)); 2314 writel(BITS_WITH_WMASK(2, 0x7U, 6), 2315 RK3576_CRU_BASE + RK3576_PLL_CON(97)); 2316 writel(BITS_WITH_WMASK(2, 0x7U, 6), 2317 RK3576_CRU_BASE + RK3576_PLL_CON(105)); 2318 writel(BITS_WITH_WMASK(1, 0x3U, 6), 2319 RK3576_CRU_BASE + RK3576_MODE_CON0); 2320 writel(BITS_WITH_WMASK(1, 0x3U, 8), 2321 RK3576_CRU_BASE + RK3576_MODE_CON0); 2322 /* init cci */ 2323 writel(0xffff0000, RK3576_CRU_BASE + RK3576_CCI_CLKSEL_CON(4)); 2324 rockchip_pll_set_rate(&rk3576_pll_clks[BPLL], priv->cru, 2325 BPLL, LPLL_HZ); 2326 if (!priv->armclk_enter_hz) { 2327 ret = rockchip_pll_set_rate(&rk3576_pll_clks[LPLL], priv->cru, 2328 LPLL, LPLL_HZ); 2329 priv->armclk_enter_hz = 2330 rockchip_pll_get_rate(&rk3576_pll_clks[LPLL], 2331 priv->cru, LPLL); 2332 priv->armclk_init_hz = priv->armclk_enter_hz; 2333 rk_clrsetreg(&priv->cru->litclksel_con[0], CLK_LITCORE_DIV_MASK, 2334 0 << CLK_LITCORE_DIV_SHIFT); 2335 } 2336 /* init cci */ 2337 writel(0xffff20cb, RK3576_CRU_BASE + RK3576_CCI_CLKSEL_CON(4)); 2338 2339 /* Change bigcore rm from 4 to 3 */ 2340 writel(0x001c000c, RK3576_BIGCORE_GRF_BASE + 0x3c); 2341 writel(0x001c000c, RK3576_BIGCORE_GRF_BASE + 0x44); 2342 writel(0x00020002, RK3576_BIGCORE_GRF_BASE + 0x38); 2343 udelay(1); 2344 writel(0x00020000, RK3576_BIGCORE_GRF_BASE + 0x38); 2345 /* Change litcore rm from 4 to 3 */ 2346 writel(0x001c000c, RK3576_LITCORE_GRF_BASE + 0x3c); 2347 writel(0x001c000c, RK3576_LITCORE_GRF_BASE + 0x44); 2348 writel(0x00020002, RK3576_LITCORE_GRF_BASE + 0x38); 2349 udelay(1); 2350 writel(0x00020000, RK3576_LITCORE_GRF_BASE + 0x38); 2351 /* Change cci rm form 4 to 3 */ 2352 writel(0x001c000c, RK3576_CCI_GRF_BASE + 0x54); 2353 #endif 2354 2355 priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 2356 if (IS_ERR(priv->grf)) 2357 return PTR_ERR(priv->grf); 2358 2359 rk3576_clk_init(priv); 2360 2361 #if CONFIG_IS_ENABLED(CLK_SCMI) 2362 #ifndef CONFIG_SPL_BUILD 2363 ret = rockchip_get_scmi_clk(&clk.dev); 2364 if (ret) { 2365 printf("Failed to get scmi clk dev, ret=%d\n", ret); 2366 return ret; 2367 } 2368 if (!priv->armclk_enter_hz) { 2369 clk.id = ARMCLK_L; 2370 ret = clk_set_rate(&clk, CPU_PVTPLL_HZ); 2371 if (ret < 0) { 2372 printf("Failed to set cpubl, ret=%d\n", ret); 2373 } else { 2374 priv->armclk_enter_hz = CPU_PVTPLL_HZ; 2375 priv->armclk_init_hz = CPU_PVTPLL_HZ; 2376 } 2377 } 2378 clk.id = ARMCLK_B; 2379 ret = clk_set_rate(&clk, CPU_PVTPLL_HZ); 2380 if (ret < 0) 2381 printf("Failed to set cpub, ret=%d\n", ret); 2382 #endif 2383 #endif 2384 2385 /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */ 2386 ret = clk_set_defaults(dev); 2387 if (ret) 2388 debug("%s clk_set_defaults failed %d\n", __func__, ret); 2389 else 2390 priv->sync_kernel = true; 2391 2392 return 0; 2393 } 2394 2395 static int rk3576_clk_ofdata_to_platdata(struct udevice *dev) 2396 { 2397 struct rk3576_clk_priv *priv = dev_get_priv(dev); 2398 2399 priv->cru = dev_read_addr_ptr(dev); 2400 2401 return 0; 2402 } 2403 2404 static int rk3576_clk_bind(struct udevice *dev) 2405 { 2406 int ret; 2407 struct udevice *sys_child, *sf_child; 2408 struct sysreset_reg *priv; 2409 struct softreset_reg *sf_priv; 2410 2411 /* The reset driver does not have a device node, so bind it here */ 2412 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset", 2413 &sys_child); 2414 if (ret) { 2415 debug("Warning: No sysreset driver: ret=%d\n", ret); 2416 } else { 2417 priv = malloc(sizeof(struct sysreset_reg)); 2418 priv->glb_srst_fst_value = offsetof(struct rk3576_cru, 2419 glb_srst_fst); 2420 priv->glb_srst_snd_value = offsetof(struct rk3576_cru, 2421 glb_srsr_snd); 2422 sys_child->priv = priv; 2423 } 2424 2425 ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset", 2426 dev_ofnode(dev), &sf_child); 2427 if (ret) { 2428 debug("Warning: No rockchip reset driver: ret=%d\n", ret); 2429 } else { 2430 sf_priv = malloc(sizeof(struct softreset_reg)); 2431 sf_priv->sf_reset_offset = offsetof(struct rk3576_cru, 2432 softrst_con[0]); 2433 sf_priv->sf_reset_num = 524454; 2434 sf_child->priv = sf_priv; 2435 } 2436 2437 return 0; 2438 } 2439 2440 static const struct udevice_id rk3576_clk_ids[] = { 2441 { .compatible = "rockchip,rk3576-cru" }, 2442 { } 2443 }; 2444 2445 U_BOOT_DRIVER(rockchip_rk3576_cru) = { 2446 .name = "rockchip_rk3576_cru", 2447 .id = UCLASS_CLK, 2448 .of_match = rk3576_clk_ids, 2449 .priv_auto_alloc_size = sizeof(struct rk3576_clk_priv), 2450 .ofdata_to_platdata = rk3576_clk_ofdata_to_platdata, 2451 .ops = &rk3576_clk_ops, 2452 .bind = rk3576_clk_bind, 2453 .probe = rk3576_clk_probe, 2454 }; 2455 2456 #ifndef CONFIG_SPL_BUILD 2457 /** 2458 * soc_clk_dump() - Print clock frequencies 2459 * Returns zero on success 2460 * 2461 * Implementation for the clk dump command. 2462 */ 2463 int soc_clk_dump(void) 2464 { 2465 struct udevice *cru_dev; 2466 struct rk3576_clk_priv *priv; 2467 const struct rk3576_clk_info *clk_dump; 2468 struct clk clk; 2469 unsigned long clk_count = ARRAY_SIZE(clks_dump); 2470 unsigned long rate; 2471 int i, ret; 2472 2473 ret = uclass_get_device_by_driver(UCLASS_CLK, 2474 DM_GET_DRIVER(rockchip_rk3576_cru), 2475 &cru_dev); 2476 if (ret) { 2477 printf("%s failed to get cru device\n", __func__); 2478 return ret; 2479 } 2480 2481 priv = dev_get_priv(cru_dev); 2482 printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n", 2483 priv->sync_kernel ? "sync kernel" : "uboot", 2484 priv->armclk_enter_hz / 1000, 2485 priv->armclk_init_hz / 1000, 2486 priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0, 2487 priv->set_armclk_rate ? " KHz" : "N/A"); 2488 for (i = 0; i < clk_count; i++) { 2489 clk_dump = &clks_dump[i]; 2490 if (clk_dump->name) { 2491 memset(&clk, 0, sizeof(struct clk)); 2492 clk.id = clk_dump->id; 2493 if (clk_dump->is_cru) 2494 ret = clk_request(cru_dev, &clk); 2495 if (ret < 0) 2496 return ret; 2497 2498 rate = clk_get_rate(&clk); 2499 clk_free(&clk); 2500 if (rate < 0) 2501 printf(" %s %s\n", clk_dump->name, 2502 "unknown"); 2503 else 2504 printf(" %s %lu KHz\n", clk_dump->name, 2505 rate / 1000); 2506 } 2507 } 2508 2509 return 0; 2510 } 2511 #endif 2512