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