1 /* 2 * (C) Copyright 2017 Rockchip Electronics Co., Ltd 3 * 4 * SPDX-License-Identifier: GPL-2.0 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_rk3328.h> 15 #include <asm/arch/hardware.h> 16 #include <asm/arch/grf_rk3328.h> 17 #include <asm/io.h> 18 #include <dm/lists.h> 19 #include <dt-bindings/clock/rk3328-cru.h> 20 21 DECLARE_GLOBAL_DATA_PTR; 22 23 #define RATE_TO_DIV(input_rate, output_rate) \ 24 ((input_rate) / (output_rate) - 1); 25 #define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1)) 26 27 #ifndef CONFIG_SPL_BUILD 28 #define RK3328_CLK_DUMP(_id, _name, _iscru) \ 29 { \ 30 .id = _id, \ 31 .name = _name, \ 32 .is_cru = _iscru, \ 33 } 34 #endif 35 36 static struct rockchip_pll_rate_table rk3328_pll_rates[] = { 37 /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */ 38 RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0), 39 #ifndef CONFIG_SPL_BUILD 40 RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0), 41 RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0), 42 #endif 43 RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0), 44 RK3036_PLL_RATE(800000000, 1, 200, 6, 1, 1, 0), 45 RK3036_PLL_RATE(600000000, 1, 75, 3, 1, 1, 0), 46 #ifndef CONFIG_SPL_BUILD 47 RK3036_PLL_RATE(594000000, 1, 99, 4, 1, 1, 0), 48 RK3036_PLL_RATE(500000000, 1, 125, 6, 1, 1, 0), 49 #endif 50 { /* sentinel */ }, 51 }; 52 53 static struct rockchip_pll_rate_table rk3328_pll_frac_rates[] = { 54 /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */ 55 #ifndef CONFIG_SPL_BUILD 56 RK3036_PLL_RATE(1016064000, 3, 127, 1, 1, 0, 134217), 57 /* vco = 1016064000 */ 58 RK3036_PLL_RATE(983040000, 24, 983, 1, 1, 0, 671088), 59 /* vco = 983040000 */ 60 #endif 61 RK3036_PLL_RATE(491520000, 24, 983, 2, 1, 0, 671088), 62 /* vco = 983040000 */ 63 #ifndef CONFIG_SPL_BUILD 64 RK3036_PLL_RATE(61440000, 6, 215, 7, 2, 0, 671088), 65 /* vco = 860156000 */ 66 RK3036_PLL_RATE(56448000, 12, 451, 4, 4, 0, 9797894), 67 /* vco = 903168000 */ 68 RK3036_PLL_RATE(40960000, 12, 409, 4, 5, 0, 10066329), 69 /* vco = 819200000 */ 70 #endif 71 { /* sentinel */ }, 72 }; 73 74 #define RK3328_CPUCLK_RATE(_rate, _aclk_div, _pclk_div) \ 75 { \ 76 .rate = _rate##U, \ 77 .aclk_div = _aclk_div, \ 78 .pclk_div = _pclk_div, \ 79 } 80 81 static struct rockchip_cpu_rate_table rk3328_cpu_rates[] = { 82 RK3328_CPUCLK_RATE(1200000000, 1, 5), 83 RK3328_CPUCLK_RATE(1008000000, 1, 5), 84 RK3328_CPUCLK_RATE(816000000, 1, 3), 85 RK3328_CPUCLK_RATE(600000000, 1, 3), 86 }; 87 88 #ifndef CONFIG_SPL_BUILD 89 static const struct rk3328_clk_info clks_dump[] = { 90 RK3328_CLK_DUMP(PLL_APLL, "apll", true), 91 RK3328_CLK_DUMP(PLL_DPLL, "dpll", true), 92 RK3328_CLK_DUMP(PLL_CPLL, "cpll", true), 93 RK3328_CLK_DUMP(PLL_GPLL, "gpll", true), 94 RK3328_CLK_DUMP(PLL_NPLL, "npll", true), 95 RK3328_CLK_DUMP(ARMCLK, "armclk", true), 96 RK3328_CLK_DUMP(ACLK_BUS_PRE, "aclk_bus", true), 97 RK3328_CLK_DUMP(HCLK_BUS_PRE, "hclk_bus", true), 98 RK3328_CLK_DUMP(PCLK_BUS_PRE, "pclk_bus", true), 99 RK3328_CLK_DUMP(ACLK_PERI_PRE, "aclk_peri", true), 100 RK3328_CLK_DUMP(HCLK_PERI, "hclk_peri", true), 101 RK3328_CLK_DUMP(PCLK_PERI, "pclk_peri", true), 102 }; 103 #endif 104 105 static struct rockchip_pll_clock rk3328_pll_clks[] = { 106 [APLL] = PLL(pll_rk3328, PLL_APLL, RK3328_PLL_CON(0), 107 RK3328_MODE_CON, 0, 10, 0, rk3328_pll_frac_rates), 108 [DPLL] = PLL(pll_rk3328, PLL_DPLL, RK3328_PLL_CON(8), 109 RK3328_MODE_CON, 4, 10, 0, NULL), 110 [CPLL] = PLL(pll_rk3328, PLL_CPLL, RK3328_PLL_CON(16), 111 RK3328_MODE_CON, 8, 10, 0, rk3328_pll_rates), 112 [GPLL] = PLL(pll_rk3328, PLL_GPLL, RK3328_PLL_CON(24), 113 RK3328_MODE_CON, 12, 10, 0, rk3328_pll_frac_rates), 114 [NPLL] = PLL(pll_rk3328, PLL_NPLL, RK3328_PLL_CON(40), 115 RK3328_MODE_CON, 1, 10, 0, rk3328_pll_rates), 116 }; 117 118 static ulong rk3328_armclk_set_clk(struct rk3328_clk_priv *priv, ulong hz) 119 { 120 struct rk3328_cru *cru = priv->cru; 121 const struct rockchip_cpu_rate_table *rate; 122 ulong old_rate; 123 124 rate = rockchip_get_cpu_settings(rk3328_cpu_rates, hz); 125 if (!rate) { 126 printf("%s unsupported rate\n", __func__); 127 return -EINVAL; 128 } 129 130 /* 131 * select apll as cpu/core clock pll source and 132 * set up dependent divisors for PERI and ACLK clocks. 133 * core hz : apll = 1:1 134 */ 135 old_rate = rockchip_pll_get_rate(&rk3328_pll_clks[NPLL], 136 priv->cru, NPLL); 137 if (old_rate > hz) { 138 if (rockchip_pll_set_rate(&rk3328_pll_clks[NPLL], 139 priv->cru, NPLL, hz)) 140 return -EINVAL; 141 rk_clrsetreg(&cru->clksel_con[0], 142 CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK, 143 CORE_CLK_PLL_SEL_NPLL << CORE_CLK_PLL_SEL_SHIFT | 144 0 << CORE_DIV_CON_SHIFT); 145 rk_clrsetreg(&cru->clksel_con[1], 146 CORE_ACLK_DIV_MASK | CORE_DBG_DIV_MASK, 147 rate->aclk_div << CORE_ACLK_DIV_SHIFT | 148 rate->pclk_div << CORE_DBG_DIV_SHIFT); 149 } else if (old_rate < hz) { 150 rk_clrsetreg(&cru->clksel_con[1], 151 CORE_ACLK_DIV_MASK | CORE_DBG_DIV_MASK, 152 rate->aclk_div << CORE_ACLK_DIV_SHIFT | 153 rate->pclk_div << CORE_DBG_DIV_SHIFT); 154 rk_clrsetreg(&cru->clksel_con[0], 155 CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK, 156 CORE_CLK_PLL_SEL_NPLL << CORE_CLK_PLL_SEL_SHIFT | 157 0 << CORE_DIV_CON_SHIFT); 158 if (rockchip_pll_set_rate(&rk3328_pll_clks[NPLL], 159 priv->cru, NPLL, hz)) 160 return -EINVAL; 161 } 162 163 return rockchip_pll_get_rate(&rk3328_pll_clks[NPLL], priv->cru, NPLL); 164 } 165 166 #ifndef CONFIG_SPL_BUILD 167 static ulong rk3328_i2c_get_clk(struct rk3328_clk_priv *priv, ulong clk_id) 168 { 169 struct rk3328_cru *cru = priv->cru; 170 u32 div, con; 171 172 switch (clk_id) { 173 case SCLK_I2C0: 174 con = readl(&cru->clksel_con[34]); 175 div = con >> CLK_I2C0_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK; 176 break; 177 case SCLK_I2C1: 178 con = readl(&cru->clksel_con[34]); 179 div = con >> CLK_I2C1_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK; 180 break; 181 case SCLK_I2C2: 182 con = readl(&cru->clksel_con[35]); 183 div = con >> CLK_I2C2_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK; 184 break; 185 case SCLK_I2C3: 186 con = readl(&cru->clksel_con[35]); 187 div = con >> CLK_I2C3_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK; 188 break; 189 default: 190 printf("do not support this i2c bus\n"); 191 return -EINVAL; 192 } 193 194 return DIV_TO_RATE(priv->gpll_hz, div); 195 } 196 197 static ulong rk3328_i2c_set_clk(struct rk3328_clk_priv *priv, 198 ulong clk_id, uint hz) 199 { 200 struct rk3328_cru *cru = priv->cru; 201 int src_clk_div; 202 203 src_clk_div = priv->gpll_hz / hz; 204 assert(src_clk_div - 1 < 127); 205 206 switch (clk_id) { 207 case SCLK_I2C0: 208 rk_clrsetreg(&cru->clksel_con[34], 209 CLK_I2C_DIV_CON_MASK << CLK_I2C0_DIV_CON_SHIFT | 210 CLK_I2C_PLL_SEL_MASK << CLK_I2C0_PLL_SEL_SHIFT, 211 (src_clk_div - 1) << CLK_I2C0_DIV_CON_SHIFT | 212 CLK_I2C_PLL_SEL_GPLL << CLK_I2C0_PLL_SEL_SHIFT); 213 break; 214 case SCLK_I2C1: 215 rk_clrsetreg(&cru->clksel_con[34], 216 CLK_I2C_DIV_CON_MASK << CLK_I2C1_DIV_CON_SHIFT | 217 CLK_I2C_PLL_SEL_MASK << CLK_I2C1_PLL_SEL_SHIFT, 218 (src_clk_div - 1) << CLK_I2C1_DIV_CON_SHIFT | 219 CLK_I2C_PLL_SEL_GPLL << CLK_I2C1_PLL_SEL_SHIFT); 220 break; 221 case SCLK_I2C2: 222 rk_clrsetreg(&cru->clksel_con[35], 223 CLK_I2C_DIV_CON_MASK << CLK_I2C2_DIV_CON_SHIFT | 224 CLK_I2C_PLL_SEL_MASK << CLK_I2C2_PLL_SEL_SHIFT, 225 (src_clk_div - 1) << CLK_I2C2_DIV_CON_SHIFT | 226 CLK_I2C_PLL_SEL_GPLL << CLK_I2C2_PLL_SEL_SHIFT); 227 break; 228 case SCLK_I2C3: 229 rk_clrsetreg(&cru->clksel_con[35], 230 CLK_I2C_DIV_CON_MASK << CLK_I2C3_DIV_CON_SHIFT | 231 CLK_I2C_PLL_SEL_MASK << CLK_I2C3_PLL_SEL_SHIFT, 232 (src_clk_div - 1) << CLK_I2C3_DIV_CON_SHIFT | 233 CLK_I2C_PLL_SEL_GPLL << CLK_I2C3_PLL_SEL_SHIFT); 234 break; 235 default: 236 printf("do not support this i2c bus\n"); 237 return -EINVAL; 238 } 239 240 return DIV_TO_RATE(priv->gpll_hz, src_clk_div); 241 } 242 243 static ulong rk3328_gmac2io_set_clk(struct rk3328_clk_priv *priv, ulong rate) 244 { 245 struct rk3328_cru *cru = priv->cru; 246 struct rk3328_grf_regs *grf; 247 ulong ret; 248 249 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 250 251 /* 252 * The RGMII CLK can be derived either from an external "clkin" 253 * or can be generated from internally by a divider from SCLK_MAC. 254 */ 255 if (readl(&grf->mac_con[1]) & BIT(10) && 256 readl(&grf->soc_con[4]) & BIT(14)) { 257 /* An external clock will always generate the right rate... */ 258 ret = rate; 259 } else { 260 u32 con = readl(&cru->clksel_con[27]); 261 ulong pll_rate; 262 u8 div; 263 264 if ((con >> GMAC2IO_PLL_SEL_SHIFT) & GMAC2IO_PLL_SEL_GPLL) 265 pll_rate = priv->gpll_hz; 266 else 267 pll_rate = priv->cpll_hz; 268 269 div = DIV_ROUND_UP(pll_rate, rate) - 1; 270 if (div <= 0x1f) 271 rk_clrsetreg(&cru->clksel_con[27], GMAC2IO_CLK_DIV_MASK, 272 div << GMAC2IO_CLK_DIV_SHIFT); 273 else 274 debug("Unsupported div for gmac:%d\n", div); 275 276 return DIV_TO_RATE(pll_rate, div); 277 } 278 279 return ret; 280 } 281 282 static ulong rk3328_gmac2phy_src_set_clk(struct rk3328_cru *cru, ulong rate) 283 { 284 u32 con = readl(&cru->clksel_con[26]); 285 ulong pll_rate; 286 u8 div; 287 288 if ((con >> GMAC2PHY_PLL_SEL_SHIFT) & GMAC2PHY_PLL_SEL_GPLL) 289 pll_rate = GPLL_HZ; 290 else 291 pll_rate = CPLL_HZ; 292 293 div = DIV_ROUND_UP(pll_rate, rate) - 1; 294 if (div <= 0x1f) 295 rk_clrsetreg(&cru->clksel_con[26], GMAC2PHY_CLK_DIV_MASK, 296 div << GMAC2PHY_CLK_DIV_SHIFT); 297 else 298 debug("Unsupported div for gmac:%d\n", div); 299 300 return DIV_TO_RATE(pll_rate, div); 301 } 302 303 static ulong rk3328_gmac2phy_set_clk(struct rk3328_cru *cru, ulong rate) 304 { 305 struct rk3328_grf_regs *grf; 306 307 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 308 if (readl(&grf->mac_con[2]) & BIT(10)) 309 /* An external clock will always generate the right rate... */ 310 return rate; 311 else 312 return rk3328_gmac2phy_src_set_clk(cru, rate); 313 } 314 #endif 315 316 static ulong rk3328_mmc_get_clk(struct rk3328_clk_priv *priv, uint clk_id) 317 { 318 struct rk3328_cru *cru = priv->cru; 319 u32 div, con, con_id; 320 321 switch (clk_id) { 322 case HCLK_SDMMC: 323 case SCLK_SDMMC: 324 con_id = 30; 325 break; 326 case HCLK_EMMC: 327 case SCLK_EMMC: 328 case SCLK_EMMC_SAMPLE: 329 con_id = 32; 330 break; 331 default: 332 return -EINVAL; 333 } 334 con = readl(&cru->clksel_con[con_id]); 335 div = (con & CLK_EMMC_DIV_CON_MASK) >> CLK_EMMC_DIV_CON_SHIFT; 336 337 if ((con & CLK_EMMC_PLL_MASK) >> CLK_EMMC_PLL_SHIFT 338 == CLK_EMMC_PLL_SEL_24M) 339 return DIV_TO_RATE(OSC_HZ, div) / 2; 340 else 341 return DIV_TO_RATE(priv->gpll_hz, div) / 2; 342 } 343 344 static ulong rk3328_mmc_set_clk(struct rk3328_clk_priv *priv, 345 ulong clk_id, ulong set_rate) 346 { 347 struct rk3328_cru *cru = priv->cru; 348 int src_clk_div; 349 u32 con_id; 350 351 switch (clk_id) { 352 case HCLK_SDMMC: 353 case SCLK_SDMMC: 354 con_id = 30; 355 break; 356 case HCLK_EMMC: 357 case SCLK_EMMC: 358 con_id = 32; 359 break; 360 default: 361 return -EINVAL; 362 } 363 /* Select clk_sdmmc/emmc source from GPLL by default */ 364 /* mmc clock defaulg div 2 internal, need provide double in cru */ 365 src_clk_div = DIV_ROUND_UP(priv->gpll_hz / 2, set_rate); 366 367 if (src_clk_div > 127) { 368 /* use 24MHz source for 400KHz clock */ 369 src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, set_rate); 370 rk_clrsetreg(&cru->clksel_con[con_id], 371 CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK, 372 CLK_EMMC_PLL_SEL_24M << CLK_EMMC_PLL_SHIFT | 373 (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT); 374 } else { 375 rk_clrsetreg(&cru->clksel_con[con_id], 376 CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK, 377 CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT | 378 (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT); 379 } 380 381 return rk3328_mmc_get_clk(priv, clk_id); 382 } 383 384 static ulong rk3328_spi_get_clk(struct rk3328_clk_priv *priv) 385 { 386 struct rk3328_cru *cru = priv->cru; 387 u32 div, con, mux, p_rate; 388 389 con = readl(&cru->clksel_con[24]); 390 div = (con & CLK_SPI_DIV_CON_MASK) >> CLK_SPI_DIV_CON_SHIFT; 391 mux = (con & CLK_SPI_PLL_SEL_MASK) >> CLK_SPI_PLL_SEL_SHIFT; 392 if (mux) 393 p_rate = priv->gpll_hz; 394 else 395 p_rate = priv->cpll_hz; 396 397 return DIV_TO_RATE(p_rate, div); 398 } 399 400 static ulong rk3328_spi_set_clk(struct rk3328_clk_priv *priv, uint hz) 401 { 402 struct rk3328_cru *cru = priv->cru; 403 u32 div = priv->gpll_hz / hz; 404 405 rk_clrsetreg(&cru->clksel_con[24], 406 CLK_SPI_PLL_SEL_MASK | CLK_SPI_DIV_CON_MASK, 407 CLK_SPI_PLL_SEL_GPLL << CLK_SPI_PLL_SEL_SHIFT | 408 (div - 1) << CLK_SPI_DIV_CON_SHIFT); 409 410 return DIV_TO_RATE(priv->gpll_hz, div); 411 } 412 413 #ifndef CONFIG_SPL_BUILD 414 static ulong rk3328_pwm_get_clk(struct rk3328_clk_priv *priv) 415 { 416 struct rk3328_cru *cru = priv->cru; 417 u32 div, con; 418 419 con = readl(&cru->clksel_con[24]); 420 div = (con & CLK_PWM_DIV_CON_MASK) >> CLK_PWM_DIV_CON_SHIFT; 421 422 return DIV_TO_RATE(priv->gpll_hz, div); 423 } 424 425 static ulong rk3328_pwm_set_clk(struct rk3328_clk_priv *priv, uint hz) 426 { 427 struct rk3328_cru *cru = priv->cru; 428 u32 div = priv->gpll_hz / hz; 429 430 rk_clrsetreg(&cru->clksel_con[24], 431 CLK_PWM_PLL_SEL_MASK | CLK_PWM_DIV_CON_MASK, 432 CLK_PWM_PLL_SEL_GPLL << CLK_PWM_PLL_SEL_SHIFT | 433 (div - 1) << CLK_PWM_DIV_CON_SHIFT); 434 435 return DIV_TO_RATE(priv->gpll_hz, div); 436 } 437 438 static ulong rk3328_saradc_get_clk(struct rk3328_clk_priv *priv) 439 { 440 struct rk3328_cru *cru = priv->cru; 441 u32 div, val; 442 443 val = readl(&cru->clksel_con[23]); 444 div = bitfield_extract(val, CLK_SARADC_DIV_CON_SHIFT, 445 CLK_SARADC_DIV_CON_WIDTH); 446 447 return DIV_TO_RATE(OSC_HZ, div); 448 } 449 450 static ulong rk3328_saradc_set_clk(struct rk3328_clk_priv *priv, uint hz) 451 { 452 struct rk3328_cru *cru = priv->cru; 453 int src_clk_div; 454 455 src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1; 456 assert(src_clk_div < 128); 457 458 rk_clrsetreg(&cru->clksel_con[23], 459 CLK_SARADC_DIV_CON_MASK, 460 src_clk_div << CLK_SARADC_DIV_CON_SHIFT); 461 462 return rk3328_saradc_get_clk(priv); 463 } 464 465 static ulong rk3328_tsadc_get_clk(struct rk3328_clk_priv *priv) 466 { 467 struct rk3328_cru *cru = priv->cru; 468 u32 div, val; 469 470 val = readl(&cru->clksel_con[22]); 471 div = bitfield_extract(val, CLK_SARADC_DIV_CON_SHIFT, 472 CLK_SARADC_DIV_CON_WIDTH); 473 474 return DIV_TO_RATE(OSC_HZ, div); 475 } 476 477 static ulong rk3328_tsadc_set_clk(struct rk3328_clk_priv *priv, uint hz) 478 { 479 struct rk3328_cru *cru = priv->cru; 480 int src_clk_div; 481 482 src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1; 483 assert(src_clk_div < 128); 484 485 rk_clrsetreg(&cru->clksel_con[22], 486 CLK_SARADC_DIV_CON_MASK, 487 src_clk_div << CLK_SARADC_DIV_CON_SHIFT); 488 489 return rk3328_tsadc_get_clk(priv); 490 } 491 492 static ulong rk3328_vop_get_clk(struct rk3328_clk_priv *priv, ulong clk_id) 493 { 494 struct rk3328_cru *cru = priv->cru; 495 u32 div, con, parent; 496 497 switch (clk_id) { 498 case ACLK_VOP_PRE: 499 case ACLK_VOP: 500 con = readl(&cru->clksel_con[39]); 501 div = (con & ACLK_VOP_DIV_CON_MASK) >> ACLK_VOP_DIV_CON_SHIFT; 502 parent = priv->cpll_hz; 503 break; 504 case ACLK_VIO_PRE: 505 case ACLK_VIO: 506 con = readl(&cru->clksel_con[37]); 507 div = (con & ACLK_VIO_DIV_CON_MASK) >> ACLK_VIO_DIV_CON_SHIFT; 508 parent = priv->cpll_hz; 509 break; 510 case HCLK_VIO_PRE: 511 case HCLK_VIO: 512 parent = rk3328_vop_get_clk(priv, ACLK_VIO_PRE); 513 con = readl(&cru->clksel_con[37]); 514 div = (con & HCLK_VIO_DIV_CON_MASK) >> HCLK_VIO_DIV_CON_SHIFT; 515 break; 516 default: 517 return -ENOENT; 518 } 519 520 return DIV_TO_RATE(parent, div); 521 } 522 523 static ulong rk3328_vop_set_clk(struct rk3328_clk_priv *priv, 524 ulong clk_id, uint hz) 525 { 526 struct rk3328_cru *cru = priv->cru; 527 int src_clk_div; 528 u32 con, parent; 529 530 src_clk_div = DIV_ROUND_UP(priv->cpll_hz, hz); 531 assert(src_clk_div - 1 < 31); 532 533 switch (clk_id) { 534 case ACLK_VOP_PRE: 535 case ACLK_VOP: 536 rk_clrsetreg(&cru->clksel_con[39], 537 ACLK_VOP_PLL_SEL_MASK | ACLK_VOP_DIV_CON_MASK, 538 ACLK_VOP_PLL_SEL_CPLL << ACLK_VOP_PLL_SEL_SHIFT | 539 (src_clk_div - 1) << ACLK_VOP_DIV_CON_SHIFT); 540 break; 541 case ACLK_VIO_PRE: 542 case ACLK_VIO: 543 rk_clrsetreg(&cru->clksel_con[37], 544 ACLK_VIO_PLL_SEL_MASK | ACLK_VIO_DIV_CON_MASK, 545 ACLK_VIO_PLL_SEL_CPLL << ACLK_VIO_PLL_SEL_SHIFT | 546 (src_clk_div - 1) << ACLK_VIO_DIV_CON_SHIFT); 547 break; 548 case HCLK_VIO_PRE: 549 case HCLK_VIO: 550 src_clk_div = DIV_ROUND_UP(rk3328_vop_get_clk(priv, 551 ACLK_VIO_PRE), 552 hz); 553 rk_clrsetreg(&cru->clksel_con[37], 554 HCLK_VIO_DIV_CON_MASK, 555 (src_clk_div - 1) << HCLK_VIO_DIV_CON_SHIFT); 556 break; 557 case DCLK_LCDC: 558 con = readl(&cru->clksel_con[40]); 559 con = (con & DCLK_LCDC_SEL_MASK) >> DCLK_LCDC_SEL_SHIFT; 560 if (con) { 561 parent = readl(&cru->clksel_con[40]); 562 parent = (parent & DCLK_LCDC_PLL_SEL_MASK) >> 563 DCLK_LCDC_PLL_SEL_SHIFT; 564 if (parent) 565 src_clk_div = DIV_ROUND_UP(priv->cpll_hz, hz); 566 else 567 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz); 568 569 rk_clrsetreg(&cru->clksel_con[40], 570 DCLK_LCDC_DIV_CON_MASK, 571 (src_clk_div - 1) << 572 DCLK_LCDC_DIV_CON_SHIFT); 573 } 574 break; 575 default: 576 printf("do not support this vop freq\n"); 577 return -EINVAL; 578 } 579 580 return rk3328_vop_get_clk(priv, clk_id); 581 } 582 #endif 583 584 static ulong rk3328_bus_get_clk(struct rk3328_clk_priv *priv, ulong clk_id) 585 { 586 struct rk3328_cru *cru = priv->cru; 587 u32 div, con, parent; 588 589 switch (clk_id) { 590 case ACLK_BUS_PRE: 591 con = readl(&cru->clksel_con[0]); 592 div = (con & ACLK_BUS_DIV_CON_MASK) >> ACLK_BUS_DIV_CON_SHIFT; 593 parent = priv->cpll_hz; 594 break; 595 case HCLK_BUS_PRE: 596 con = readl(&cru->clksel_con[1]); 597 div = (con & HCLK_BUS_DIV_CON_MASK) >> HCLK_BUS_DIV_CON_SHIFT; 598 parent = rk3328_bus_get_clk(priv, ACLK_BUS_PRE); 599 break; 600 case PCLK_BUS_PRE: 601 con = readl(&cru->clksel_con[1]); 602 div = (con & PCLK_BUS_DIV_CON_MASK) >> PCLK_BUS_DIV_CON_SHIFT; 603 parent = rk3328_bus_get_clk(priv, ACLK_BUS_PRE); 604 break; 605 default: 606 return -ENOENT; 607 } 608 609 return DIV_TO_RATE(parent, div); 610 } 611 612 static ulong rk3328_bus_set_clk(struct rk3328_clk_priv *priv, 613 ulong clk_id, ulong hz) 614 { 615 struct rk3328_cru *cru = priv->cru; 616 int src_clk_div; 617 618 /* 619 * select gpll as pd_bus bus clock source and 620 * set up dependent divisors for PCLK/HCLK and ACLK clocks. 621 */ 622 switch (clk_id) { 623 case ACLK_BUS_PRE: 624 src_clk_div = DIV_ROUND_UP(priv->cpll_hz, hz); 625 assert(src_clk_div - 1 < 31); 626 if (src_clk_div > 32) 627 src_clk_div = 32; 628 rk_clrsetreg(&cru->clksel_con[0], 629 CLK_BUS_PLL_SEL_MASK | ACLK_BUS_DIV_CON_MASK, 630 CLK_BUS_PLL_SEL_CPLL << CLK_BUS_PLL_SEL_SHIFT | 631 (src_clk_div - 1) << ACLK_BUS_DIV_CON_SHIFT); 632 break; 633 case HCLK_BUS_PRE: 634 src_clk_div = DIV_ROUND_UP(rk3328_bus_get_clk(priv, 635 ACLK_BUS_PRE), 636 hz); 637 assert(src_clk_div - 1 < 3); 638 rk_clrsetreg(&cru->clksel_con[1], 639 HCLK_BUS_DIV_CON_MASK, 640 (src_clk_div - 1) << HCLK_BUS_DIV_CON_SHIFT); 641 break; 642 case PCLK_BUS_PRE: 643 src_clk_div = DIV_ROUND_UP(rk3328_bus_get_clk(priv, 644 ACLK_BUS_PRE), 645 hz); 646 assert(src_clk_div - 1 < 7); 647 rk_clrsetreg(&cru->clksel_con[1], 648 PCLK_BUS_DIV_CON_MASK, 649 (src_clk_div - 1) << PCLK_BUS_DIV_CON_SHIFT); 650 break; 651 default: 652 printf("do not support this bus freq\n"); 653 return -EINVAL; 654 } 655 return rk3328_bus_get_clk(priv, clk_id); 656 } 657 658 static ulong rk3328_peri_get_clk(struct rk3328_clk_priv *priv, ulong clk_id) 659 { 660 struct rk3328_cru *cru = priv->cru; 661 u32 div, con, parent; 662 663 switch (clk_id) { 664 case ACLK_PERI_PRE: 665 con = readl(&cru->clksel_con[28]); 666 div = (con & ACLK_PERI_DIV_CON_MASK) >> ACLK_PERI_DIV_CON_SHIFT; 667 parent = priv->cpll_hz; 668 break; 669 case HCLK_PERI: 670 con = readl(&cru->clksel_con[29]); 671 div = (con & HCLK_PERI_DIV_CON_MASK) >> HCLK_PERI_DIV_CON_SHIFT; 672 parent = rk3328_peri_get_clk(priv, ACLK_PERI_PRE); 673 break; 674 case PCLK_PERI: 675 con = readl(&cru->clksel_con[29]); 676 div = (con & PCLK_PERI_DIV_CON_MASK) >> PCLK_PERI_DIV_CON_SHIFT; 677 parent = rk3328_peri_get_clk(priv, ACLK_PERI_PRE); 678 break; 679 default: 680 return -ENOENT; 681 } 682 683 return DIV_TO_RATE(parent, div); 684 } 685 686 static ulong rk3328_peri_set_clk(struct rk3328_clk_priv *priv, 687 ulong clk_id, ulong hz) 688 { 689 struct rk3328_cru *cru = priv->cru; 690 int src_clk_div; 691 692 /* 693 * select gpll as pd_bus bus clock source and 694 * set up dependent divisors for PCLK/HCLK and ACLK clocks. 695 */ 696 switch (clk_id) { 697 case ACLK_PERI_PRE: 698 src_clk_div = DIV_ROUND_UP(priv->cpll_hz, hz); 699 assert(src_clk_div - 1 < 31); 700 if (src_clk_div > 32) 701 src_clk_div = 32; 702 rk_clrsetreg(&cru->clksel_con[28], 703 CLK_PERI_PLL_SEL_MASK | ACLK_PERI_DIV_CON_MASK, 704 CLK_PERI_PLL_SEL_CPLL << CLK_PERI_PLL_SEL_SHIFT | 705 (src_clk_div - 1) << ACLK_PERI_DIV_CON_SHIFT); 706 break; 707 case HCLK_PERI: 708 src_clk_div = DIV_ROUND_UP(rk3328_peri_get_clk(priv, 709 ACLK_PERI_PRE), 710 hz); 711 assert(src_clk_div - 1 < 3); 712 rk_clrsetreg(&cru->clksel_con[29], 713 HCLK_PERI_DIV_CON_MASK, 714 (src_clk_div - 1) << HCLK_PERI_DIV_CON_SHIFT); 715 break; 716 case PCLK_PERI: 717 src_clk_div = DIV_ROUND_UP(rk3328_peri_get_clk(priv, 718 ACLK_PERI_PRE), 719 hz); 720 assert(src_clk_div - 1 < 7); 721 rk_clrsetreg(&cru->clksel_con[29], 722 PCLK_PERI_DIV_CON_MASK, 723 (src_clk_div - 1) << PCLK_PERI_DIV_CON_SHIFT); 724 break; 725 default: 726 printf("do not support this bus freq\n"); 727 return -EINVAL; 728 } 729 730 return rk3328_peri_get_clk(priv, clk_id); 731 } 732 733 #ifndef CONFIG_SPL_BUILD 734 static ulong rk3328_crypto_get_clk(struct rk3328_clk_priv *priv, ulong clk_id) 735 { 736 struct rk3328_cru *cru = priv->cru; 737 u32 div, con, parent; 738 739 switch (clk_id) { 740 case SCLK_CRYPTO: 741 con = readl(&cru->clksel_con[20]); 742 div = (con & CRYPTO_DIV_MASK) >> CRYPTO_DIV_SHIFT; 743 parent = priv->gpll_hz; 744 break; 745 default: 746 return -ENOENT; 747 } 748 749 return DIV_TO_RATE(parent, div); 750 } 751 752 static ulong rk3328_crypto_set_clk(struct rk3328_clk_priv *priv, ulong clk_id, 753 ulong hz) 754 { 755 struct rk3328_cru *cru = priv->cru; 756 int src_clk_div; 757 758 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz); 759 assert(src_clk_div - 1 <= 127); 760 761 /* 762 * select gpll as crypto clock source and 763 * set up dependent divisors for crypto clocks. 764 */ 765 switch (clk_id) { 766 case SCLK_CRYPTO: 767 rk_clrsetreg(&cru->clksel_con[20], 768 CRYPTO_PLL_SEL_MASK | CRYPTO_DIV_MASK, 769 CRYPTO_PLL_SEL_GPLL << CRYPTO_PLL_SEL_SHIFT | 770 (src_clk_div - 1) << CRYPTO_DIV_SHIFT); 771 break; 772 default: 773 printf("do not support this peri freq\n"); 774 return -EINVAL; 775 } 776 777 return rk3328_crypto_get_clk(priv, clk_id); 778 } 779 #endif 780 781 static ulong rk3328_clk_get_rate(struct clk *clk) 782 { 783 struct rk3328_clk_priv *priv = dev_get_priv(clk->dev); 784 ulong rate = 0; 785 786 #ifndef CONFIG_SPL_BUILD 787 if (!priv->gpll_hz) { 788 priv->gpll_hz = rockchip_pll_get_rate(&rk3328_pll_clks[GPLL], 789 priv->cru, GPLL); 790 debug("%s gpll=%lu\n", __func__, priv->gpll_hz); 791 } 792 if (!priv->cpll_hz) { 793 priv->cpll_hz = rockchip_pll_get_rate(&rk3328_pll_clks[CPLL], 794 priv->cru, CPLL); 795 debug("%s cpll=%lu\n", __func__, priv->cpll_hz); 796 } 797 #endif 798 799 switch (clk->id) { 800 case PLL_APLL: 801 case PLL_DPLL: 802 case PLL_CPLL: 803 case PLL_GPLL: 804 case PLL_NPLL: 805 rate = rockchip_pll_get_rate(&rk3328_pll_clks[clk->id - 1], 806 priv->cru, clk->id - 1); 807 break; 808 case ARMCLK: 809 rate = rockchip_pll_get_rate(&rk3328_pll_clks[NPLL], 810 priv->cru, NPLL); 811 break; 812 case ACLK_BUS_PRE: 813 case HCLK_BUS_PRE: 814 case PCLK_BUS_PRE: 815 rate = rk3328_bus_get_clk(priv, clk->id); 816 break; 817 case ACLK_PERI_PRE: 818 case HCLK_PERI: 819 case PCLK_PERI: 820 rate = rk3328_peri_get_clk(priv, clk->id); 821 break; 822 case HCLK_SDMMC: 823 case HCLK_EMMC: 824 case SCLK_SDMMC: 825 case SCLK_EMMC: 826 case SCLK_EMMC_SAMPLE: 827 rate = rk3328_mmc_get_clk(priv, clk->id); 828 break; 829 case SCLK_SPI: 830 rate = rk3328_spi_get_clk(priv); 831 break; 832 #ifndef CONFIG_SPL_BUILD 833 case SCLK_I2C0: 834 case SCLK_I2C1: 835 case SCLK_I2C2: 836 case SCLK_I2C3: 837 rate = rk3328_i2c_get_clk(priv, clk->id); 838 break; 839 case SCLK_PWM: 840 rate = rk3328_pwm_get_clk(priv); 841 break; 842 case SCLK_SARADC: 843 rate = rk3328_saradc_get_clk(priv); 844 break; 845 case SCLK_TSADC: 846 rate = rk3328_tsadc_get_clk(priv); 847 break; 848 case ACLK_VOP_PRE: 849 case ACLK_VIO_PRE: 850 case HCLK_VIO_PRE: 851 case ACLK_VOP: 852 case ACLK_VIO: 853 case HCLK_VIO: 854 rate = rk3328_vop_get_clk(priv, clk->id); 855 break; 856 case SCLK_CRYPTO: 857 rate = rk3328_crypto_get_clk(priv, clk->id); 858 break; 859 #endif 860 default: 861 return -ENOENT; 862 } 863 864 return rate; 865 } 866 867 static ulong rk3328_clk_set_rate(struct clk *clk, ulong rate) 868 { 869 struct rk3328_clk_priv *priv = dev_get_priv(clk->dev); 870 ulong ret = 0; 871 872 switch (clk->id) { 873 case PLL_APLL: 874 case PLL_DPLL: 875 case PLL_NPLL: 876 ret = rockchip_pll_set_rate(&rk3328_pll_clks[clk->id - 1], 877 priv->cru, clk->id - 1, rate); 878 break; 879 case PLL_CPLL: 880 ret = rockchip_pll_set_rate(&rk3328_pll_clks[CPLL], 881 priv->cru, CPLL, rate); 882 priv->cpll_hz = rate; 883 break; 884 case PLL_GPLL: 885 ret = rockchip_pll_set_rate(&rk3328_pll_clks[GPLL], 886 priv->cru, GPLL, rate); 887 priv->gpll_hz = rate; 888 break; 889 case ARMCLK: 890 if (priv->armclk_hz) 891 ret = rk3328_armclk_set_clk(priv, rate); 892 priv->armclk_hz = rate; 893 break; 894 case ACLK_BUS_PRE: 895 case HCLK_BUS_PRE: 896 case PCLK_BUS_PRE: 897 rate = rk3328_bus_set_clk(priv, clk->id, rate); 898 break; 899 case ACLK_PERI_PRE: 900 case HCLK_PERI: 901 case PCLK_PERI: 902 rate = rk3328_peri_set_clk(priv, clk->id, rate); 903 break; 904 case HCLK_SDMMC: 905 case HCLK_EMMC: 906 case SCLK_SDMMC: 907 case SCLK_EMMC: 908 ret = rk3328_mmc_set_clk(priv, clk->id, rate); 909 break; 910 case SCLK_SPI: 911 ret = rk3328_spi_set_clk(priv, rate); 912 break; 913 #ifndef CONFIG_SPL_BUILD 914 case SCLK_I2C0: 915 case SCLK_I2C1: 916 case SCLK_I2C2: 917 case SCLK_I2C3: 918 ret = rk3328_i2c_set_clk(priv, clk->id, rate); 919 break; 920 case SCLK_MAC2IO: 921 ret = rk3328_gmac2io_set_clk(priv, rate); 922 break; 923 case SCLK_MAC2PHY: 924 ret = rk3328_gmac2phy_set_clk(priv->cru, rate); 925 break; 926 case SCLK_MAC2PHY_SRC: 927 ret = rk3328_gmac2phy_src_set_clk(priv->cru, rate); 928 break; 929 case SCLK_PWM: 930 ret = rk3328_pwm_set_clk(priv, rate); 931 break; 932 case SCLK_SARADC: 933 ret = rk3328_saradc_set_clk(priv, rate); 934 break; 935 case SCLK_TSADC: 936 ret = rk3328_tsadc_set_clk(priv, rate); 937 break; 938 case DCLK_LCDC: 939 case ACLK_VOP_PRE: 940 case ACLK_VIO_PRE: 941 case HCLK_VIO_PRE: 942 case ACLK_VOP: 943 case ACLK_VIO: 944 case HCLK_VIO: 945 rate = rk3328_vop_set_clk(priv, clk->id, rate); 946 break; 947 case SCLK_CRYPTO: 948 rate = rk3328_crypto_set_clk(priv, clk->id, rate); 949 break; 950 #endif 951 case SCLK_PDM: 952 case SCLK_RTC32K: 953 case SCLK_UART0: 954 case SCLK_UART1: 955 case SCLK_UART2: 956 case SCLK_SDIO: 957 case SCLK_TSP: 958 case SCLK_WIFI: 959 case ACLK_RGA_PRE: 960 case SCLK_RGA: 961 case ACLK_RKVDEC_PRE: 962 case ACLK_RKVENC: 963 case ACLK_VPU_PRE: 964 case SCLK_VDEC_CABAC: 965 case SCLK_VDEC_CORE: 966 case SCLK_VENC_CORE: 967 case SCLK_VENC_DSP: 968 case SCLK_EFUSE: 969 case PCLK_DDR: 970 case ACLK_GMAC: 971 case PCLK_GMAC: 972 case SCLK_USB3OTG_SUSPEND: 973 return 0; 974 default: 975 return -ENOENT; 976 } 977 978 return ret; 979 } 980 981 #ifndef CONFIG_SPL_BUILD 982 static int rk3328_gmac2io_set_parent(struct clk *clk, struct clk *parent) 983 { 984 struct rk3328_grf_regs *grf; 985 const char *clock_output_name; 986 int ret; 987 988 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 989 990 /* 991 * If the requested parent is in the same clock-controller and the id 992 * is SCLK_MAC2IO_SRC ("clk_mac2io_src"), switch to the internal clock. 993 */ 994 if ((parent->dev == clk->dev) && (parent->id == SCLK_MAC2IO_SRC)) { 995 debug("%s: switching RGMII to SCLK_MAC2IO_SRC\n", __func__); 996 rk_clrreg(&grf->mac_con[1], BIT(10)); 997 return 0; 998 } 999 1000 /* 1001 * Otherwise, we need to check the clock-output-names of the 1002 * requested parent to see if the requested id is "gmac_clkin". 1003 */ 1004 ret = dev_read_string_index(parent->dev, "clock-output-names", 1005 parent->id, &clock_output_name); 1006 if (ret < 0) 1007 return -ENODATA; 1008 1009 /* If this is "gmac_clkin", switch to the external clock input */ 1010 if (!strcmp(clock_output_name, "gmac_clkin")) { 1011 debug("%s: switching RGMII to CLKIN\n", __func__); 1012 rk_setreg(&grf->mac_con[1], BIT(10)); 1013 return 0; 1014 } 1015 1016 return -EINVAL; 1017 } 1018 1019 static int rk3328_gmac2io_ext_set_parent(struct clk *clk, struct clk *parent) 1020 { 1021 struct rk3328_grf_regs *grf; 1022 const char *clock_output_name; 1023 int ret; 1024 1025 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 1026 1027 /* 1028 * If the requested parent is in the same clock-controller and the id 1029 * is SCLK_MAC2IO ("clk_mac2io"), switch to the internal clock. 1030 */ 1031 if ((parent->dev == clk->dev) && (parent->id == SCLK_MAC2IO)) { 1032 debug("%s: switching RGMII to SCLK_MAC2IO\n", __func__); 1033 rk_clrreg(&grf->soc_con[4], BIT(14)); 1034 return 0; 1035 } 1036 1037 /* 1038 * Otherwise, we need to check the clock-output-names of the 1039 * requested parent to see if the requested id is "gmac_clkin". 1040 */ 1041 ret = dev_read_string_index(parent->dev, "clock-output-names", 1042 parent->id, &clock_output_name); 1043 if (ret < 0) 1044 return -ENODATA; 1045 1046 /* If this is "gmac_clkin", switch to the external clock input */ 1047 if (!strcmp(clock_output_name, "gmac_clkin")) { 1048 debug("%s: switching RGMII to CLKIN\n", __func__); 1049 rk_setreg(&grf->soc_con[4], BIT(14)); 1050 return 0; 1051 } 1052 1053 return -EINVAL; 1054 } 1055 1056 static int rk3328_gmac2phy_set_parent(struct clk *clk, struct clk *parent) 1057 { 1058 struct rk3328_grf_regs *grf; 1059 const char *clock_output_name; 1060 int ret; 1061 1062 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 1063 1064 /* 1065 * If the requested parent is in the same clock-controller and the id 1066 * is SCLK_MAC2PHY_SRC ("clk_mac2phy_src"), switch to the internal clock. 1067 */ 1068 if ((parent->dev == clk->dev) && (parent->id == SCLK_MAC2PHY_SRC)) { 1069 debug("%s: switching MAC CLK to SCLK_MAC2IO_PHY\n", __func__); 1070 rk_clrreg(&grf->mac_con[2], BIT(10)); 1071 return 0; 1072 } 1073 1074 /* 1075 * Otherwise, we need to check the clock-output-names of the 1076 * requested parent to see if the requested id is "phy_50m_out". 1077 */ 1078 ret = dev_read_string_index(parent->dev, "clock-output-names", 1079 parent->id, &clock_output_name); 1080 if (ret < 0) 1081 return -ENODATA; 1082 1083 /* If this is "phy_50m_out", switch to the external clock input */ 1084 if (!strcmp(clock_output_name, "phy_50m_out")) { 1085 debug("%s: switching MAC CLK to PHY_50M_OUT\n", __func__); 1086 rk_setreg(&grf->mac_con[2], BIT(10)); 1087 return 0; 1088 } 1089 1090 return -EINVAL; 1091 } 1092 1093 static int rk3328_lcdc_set_parent(struct clk *clk, struct clk *parent) 1094 { 1095 struct rk3328_clk_priv *priv = dev_get_priv(clk->dev); 1096 1097 if (parent->id == HDMIPHY) 1098 rk_clrsetreg(&priv->cru->clksel_con[40], 1099 DCLK_LCDC_SEL_MASK, 1100 DCLK_LCDC_SEL_HDMIPHY << DCLK_LCDC_SEL_SHIFT); 1101 else if (parent->id == PLL_CPLL) 1102 rk_clrsetreg(&priv->cru->clksel_con[40], 1103 DCLK_LCDC_SEL_MASK | DCLK_LCDC_PLL_SEL_MASK, 1104 (DCLK_LCDC_SEL_PLL << DCLK_LCDC_SEL_SHIFT) | 1105 (DCLK_LCDC_PLL_SEL_CPLL << 1106 DCLK_LCDC_PLL_SEL_SHIFT)); 1107 else 1108 rk_clrsetreg(&priv->cru->clksel_con[40], 1109 DCLK_LCDC_SEL_MASK | DCLK_LCDC_PLL_SEL_MASK, 1110 (DCLK_LCDC_SEL_PLL << DCLK_LCDC_SEL_SHIFT) | 1111 (DCLK_LCDC_PLL_SEL_GPLL << 1112 DCLK_LCDC_PLL_SEL_SHIFT)); 1113 1114 return 0; 1115 } 1116 #endif 1117 1118 static int rk3328_clk_set_parent(struct clk *clk, struct clk *parent) 1119 { 1120 switch (clk->id) { 1121 #ifndef CONFIG_SPL_BUILD 1122 case SCLK_MAC2IO: 1123 return rk3328_gmac2io_set_parent(clk, parent); 1124 case SCLK_MAC2IO_EXT: 1125 return rk3328_gmac2io_ext_set_parent(clk, parent); 1126 case SCLK_MAC2PHY: 1127 return rk3328_gmac2phy_set_parent(clk, parent); 1128 case DCLK_LCDC: 1129 return rk3328_lcdc_set_parent(clk, parent); 1130 #endif 1131 case SCLK_PDM: 1132 case SCLK_RTC32K: 1133 case SCLK_UART0: 1134 case SCLK_UART1: 1135 case SCLK_UART2: 1136 return 0; 1137 } 1138 1139 debug("%s: unsupported clk %ld\n", __func__, clk->id); 1140 return -ENOENT; 1141 } 1142 1143 #define ROCKCHIP_MMC_DELAY_SEL BIT(10) 1144 #define ROCKCHIP_MMC_DEGREE_MASK 0x3 1145 #define ROCKCHIP_MMC_DELAYNUM_OFFSET 2 1146 #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET) 1147 1148 #define PSECS_PER_SEC 1000000000000LL 1149 /* 1150 * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to 1151 * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg. 1152 */ 1153 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60 1154 1155 int rk3328_mmc_get_phase(struct clk *clk) 1156 { 1157 struct rk3328_clk_priv *priv = dev_get_priv(clk->dev); 1158 struct rk3328_cru *cru = priv->cru; 1159 u32 raw_value, delay_num; 1160 u16 degrees = 0; 1161 ulong rate; 1162 1163 rate = rk3328_clk_get_rate(clk); 1164 1165 if (rate < 0) 1166 return rate; 1167 1168 if (clk->id == SCLK_EMMC_SAMPLE) 1169 raw_value = readl(&cru->emmc_con[1]); 1170 else if (clk->id == SCLK_SDMMC_SAMPLE) 1171 raw_value = readl(&cru->sdmmc_con[1]); 1172 else 1173 raw_value = readl(&cru->sdio_con[1]); 1174 1175 raw_value >>= 1; 1176 degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90; 1177 1178 if (raw_value & ROCKCHIP_MMC_DELAY_SEL) { 1179 /* degrees/delaynum * 10000 */ 1180 unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) * 1181 36 * (rate / 1000000); 1182 1183 delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK); 1184 delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET; 1185 degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000); 1186 } 1187 1188 return degrees % 360; 1189 } 1190 1191 int rk3328_mmc_set_phase(struct clk *clk, u32 degrees) 1192 { 1193 struct rk3328_clk_priv *priv = dev_get_priv(clk->dev); 1194 struct rk3328_cru *cru = priv->cru; 1195 u8 nineties, remainder, delay_num; 1196 u32 raw_value, delay; 1197 ulong rate; 1198 1199 rate = rk3328_clk_get_rate(clk); 1200 1201 if (rate < 0) 1202 return rate; 1203 1204 nineties = degrees / 90; 1205 remainder = (degrees % 90); 1206 1207 /* 1208 * Convert to delay; do a little extra work to make sure we 1209 * don't overflow 32-bit / 64-bit numbers. 1210 */ 1211 delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */ 1212 delay *= remainder; 1213 delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 * 1214 (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10)); 1215 1216 delay_num = (u8)min_t(u32, delay, 255); 1217 1218 raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0; 1219 raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET; 1220 raw_value |= nineties; 1221 1222 raw_value <<= 1; 1223 if (clk->id == SCLK_EMMC_SAMPLE) 1224 writel(raw_value | 0xffff0000, &cru->emmc_con[1]); 1225 else if (clk->id == SCLK_SDMMC_SAMPLE) 1226 writel(raw_value | 0xffff0000, &cru->sdmmc_con[1]); 1227 else 1228 writel(raw_value | 0xffff0000, &cru->sdio_con[1]); 1229 1230 debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n", 1231 degrees, delay_num, raw_value, rk3328_mmc_get_phase(clk)); 1232 1233 return 0; 1234 } 1235 1236 static int rk3328_clk_get_phase(struct clk *clk) 1237 { 1238 int ret; 1239 1240 debug("%s %ld\n", __func__, clk->id); 1241 switch (clk->id) { 1242 case SCLK_EMMC_SAMPLE: 1243 case SCLK_SDMMC_SAMPLE: 1244 case SCLK_SDIO_SAMPLE: 1245 ret = rk3328_mmc_get_phase(clk); 1246 break; 1247 default: 1248 return -ENOENT; 1249 } 1250 1251 return ret; 1252 } 1253 1254 static int rk3328_clk_set_phase(struct clk *clk, int degrees) 1255 { 1256 int ret; 1257 1258 debug("%s %ld\n", __func__, clk->id); 1259 switch (clk->id) { 1260 case SCLK_EMMC_SAMPLE: 1261 case SCLK_SDMMC_SAMPLE: 1262 case SCLK_SDIO_SAMPLE: 1263 ret = rk3328_mmc_set_phase(clk, degrees); 1264 break; 1265 default: 1266 return -ENOENT; 1267 } 1268 1269 return ret; 1270 } 1271 1272 static struct clk_ops rk3328_clk_ops = { 1273 .get_rate = rk3328_clk_get_rate, 1274 .set_rate = rk3328_clk_set_rate, 1275 .set_parent = rk3328_clk_set_parent, 1276 .get_phase = rk3328_clk_get_phase, 1277 .set_phase = rk3328_clk_set_phase, 1278 }; 1279 1280 static void rkclk_init(struct rk3328_clk_priv *priv) 1281 { 1282 if (rockchip_pll_get_rate(&rk3328_pll_clks[NPLL], 1283 priv->cru, NPLL) != APLL_HZ) 1284 rk3328_armclk_set_clk(priv, APLL_HZ); 1285 1286 priv->gpll_hz = rockchip_pll_get_rate(&rk3328_pll_clks[GPLL], 1287 priv->cru, GPLL); 1288 priv->cpll_hz = rockchip_pll_get_rate(&rk3328_pll_clks[CPLL], 1289 priv->cru, CPLL); 1290 1291 /* before set pll set child div first */ 1292 rk_clrsetreg(&priv->cru->clksel_con[24], (0x3f << 8) | (0x3f << 0), 1293 (0x17 << 8) | (0x17 << 0)); 1294 rk_clrsetreg(&priv->cru->clksel_con[27], (0x1f << 8) | (0x1f << 0), 1295 (0x17 << 8) | (0x17 << 0)); 1296 rk_clrsetreg(&priv->cru->clksel_con[31], 0xff << 0, 0xb << 0); 1297 rk_clrsetreg(&priv->cru->clksel_con[43], 0xff << 0, 0xb << 0); 1298 rk_clrsetreg(&priv->cru->clksel_con[52], 0x1f << 8, 0x5 << 8); 1299 1300 rockchip_pll_set_rate(&rk3328_pll_clks[GPLL], 1301 priv->cru, GPLL, GPLL_HZ); 1302 priv->gpll_hz = GPLL_HZ; 1303 1304 rockchip_pll_set_rate(&rk3328_pll_clks[CPLL], 1305 priv->cru, CPLL, CPLL_HZ); 1306 priv->cpll_hz = CPLL_HZ; 1307 1308 rk3328_bus_set_clk(priv, ACLK_BUS_PRE, ACLK_BUS_HZ); 1309 rk3328_bus_set_clk(priv, HCLK_BUS_PRE, ACLK_BUS_HZ / 2); 1310 rk3328_bus_set_clk(priv, PCLK_BUS_PRE, ACLK_BUS_HZ / 2); 1311 rk3328_peri_set_clk(priv, ACLK_PERI_PRE, ACLK_PERI_HZ); 1312 rk3328_peri_set_clk(priv, HCLK_PERI, ACLK_PERI_HZ / 2); 1313 rk3328_peri_set_clk(priv, PCLK_PERI, ACLK_PERI_HZ / 2); 1314 /*rk3328_mmc_set_clk(priv, SCLK_EMMC, rate);*/ 1315 1316 /* set usbphy and hdmiphy from phy */ 1317 rk_clrsetreg(&priv->cru->misc, (0x1 << 13) | 1318 (0x1 << 15), (0 << 15) | (0 << 13)); 1319 } 1320 1321 static int rk3328_clk_probe(struct udevice *dev) 1322 { 1323 struct rk3328_clk_priv *priv = dev_get_priv(dev); 1324 int ret = 0; 1325 1326 priv->sync_kernel = false; 1327 if (!priv->armclk_enter_hz) 1328 priv->armclk_enter_hz = 1329 rockchip_pll_get_rate(&rk3328_pll_clks[NPLL], 1330 priv->cru, NPLL); 1331 rkclk_init(priv); 1332 if (!priv->armclk_init_hz) 1333 priv->armclk_init_hz = 1334 rockchip_pll_get_rate(&rk3328_pll_clks[NPLL], 1335 priv->cru, NPLL); 1336 1337 ret = clk_set_defaults(dev); 1338 if (ret) 1339 debug("%s clk_set_defaults failed %d\n", __func__, ret); 1340 else 1341 priv->sync_kernel = true; 1342 1343 return 0; 1344 } 1345 1346 static int rk3328_clk_ofdata_to_platdata(struct udevice *dev) 1347 { 1348 struct rk3328_clk_priv *priv = dev_get_priv(dev); 1349 1350 priv->cru = dev_read_addr_ptr(dev); 1351 1352 return 0; 1353 } 1354 1355 static int rk3328_clk_bind(struct udevice *dev) 1356 { 1357 int ret; 1358 struct udevice *sys_child, *sf_child; 1359 struct sysreset_reg *priv; 1360 struct softreset_reg *sf_priv; 1361 1362 /* The reset driver does not have a device node, so bind it here */ 1363 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset", 1364 &sys_child); 1365 if (ret) { 1366 debug("Warning: No sysreset driver: ret=%d\n", ret); 1367 } else { 1368 priv = malloc(sizeof(struct sysreset_reg)); 1369 priv->glb_srst_fst_value = offsetof(struct rk3328_cru, 1370 glb_srst_fst_value); 1371 priv->glb_srst_snd_value = offsetof(struct rk3328_cru, 1372 glb_srst_snd_value); 1373 sys_child->priv = priv; 1374 } 1375 1376 ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset", 1377 dev_ofnode(dev), &sf_child); 1378 if (ret) { 1379 debug("Warning: No rockchip reset driver: ret=%d\n", ret); 1380 } else { 1381 sf_priv = malloc(sizeof(struct softreset_reg)); 1382 sf_priv->sf_reset_offset = offsetof(struct rk3328_cru, 1383 softrst_con[0]); 1384 sf_priv->sf_reset_num = 12; 1385 sf_child->priv = sf_priv; 1386 } 1387 1388 return 0; 1389 } 1390 1391 static const struct udevice_id rk3328_clk_ids[] = { 1392 { .compatible = "rockchip,rk3328-cru" }, 1393 { } 1394 }; 1395 1396 U_BOOT_DRIVER(rockchip_rk3328_cru) = { 1397 .name = "rockchip_rk3328_cru", 1398 .id = UCLASS_CLK, 1399 .of_match = rk3328_clk_ids, 1400 .priv_auto_alloc_size = sizeof(struct rk3328_clk_priv), 1401 .ofdata_to_platdata = rk3328_clk_ofdata_to_platdata, 1402 .ops = &rk3328_clk_ops, 1403 .bind = rk3328_clk_bind, 1404 .probe = rk3328_clk_probe, 1405 }; 1406 1407 #ifndef CONFIG_SPL_BUILD 1408 /** 1409 * soc_clk_dump() - Print clock frequencies 1410 * Returns zero on success 1411 * 1412 * Implementation for the clk dump command. 1413 */ 1414 int soc_clk_dump(void) 1415 { 1416 struct udevice *cru_dev; 1417 struct rk3328_clk_priv *priv; 1418 const struct rk3328_clk_info *clk_dump; 1419 struct clk clk; 1420 unsigned long clk_count = ARRAY_SIZE(clks_dump); 1421 unsigned long rate; 1422 int i, ret; 1423 1424 ret = uclass_get_device_by_driver(UCLASS_CLK, 1425 DM_GET_DRIVER(rockchip_rk3328_cru), 1426 &cru_dev); 1427 if (ret) { 1428 printf("%s failed to get cru device\n", __func__); 1429 return ret; 1430 } 1431 1432 priv = dev_get_priv(cru_dev); 1433 printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n", 1434 priv->sync_kernel ? "sync kernel" : "uboot", 1435 priv->armclk_enter_hz / 1000, 1436 priv->armclk_init_hz / 1000, 1437 priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0, 1438 priv->set_armclk_rate ? " KHz" : "N/A"); 1439 for (i = 0; i < clk_count; i++) { 1440 clk_dump = &clks_dump[i]; 1441 if (clk_dump->name) { 1442 clk.id = clk_dump->id; 1443 if (clk_dump->is_cru) 1444 ret = clk_request(cru_dev, &clk); 1445 if (ret < 0) 1446 return ret; 1447 1448 rate = clk_get_rate(&clk); 1449 clk_free(&clk); 1450 if (i == 0) { 1451 if (rate < 0) 1452 printf(" %s %s\n", clk_dump->name, 1453 "unknown"); 1454 else 1455 printf(" %s %lu KHz\n", clk_dump->name, 1456 rate / 1000); 1457 } else { 1458 if (rate < 0) 1459 printf(" %s %s\n", clk_dump->name, 1460 "unknown"); 1461 else 1462 printf(" %s %lu KHz\n", clk_dump->name, 1463 rate / 1000); 1464 } 1465 } 1466 } 1467 1468 return 0; 1469 } 1470 #endif 1471