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 #endif 282 283 static ulong rk3328_mmc_get_clk(struct rk3328_clk_priv *priv, uint clk_id) 284 { 285 struct rk3328_cru *cru = priv->cru; 286 u32 div, con, con_id; 287 288 switch (clk_id) { 289 case HCLK_SDMMC: 290 case SCLK_SDMMC: 291 con_id = 30; 292 break; 293 case HCLK_EMMC: 294 case SCLK_EMMC: 295 case SCLK_EMMC_SAMPLE: 296 con_id = 32; 297 break; 298 default: 299 return -EINVAL; 300 } 301 con = readl(&cru->clksel_con[con_id]); 302 div = (con & CLK_EMMC_DIV_CON_MASK) >> CLK_EMMC_DIV_CON_SHIFT; 303 304 if ((con & CLK_EMMC_PLL_MASK) >> CLK_EMMC_PLL_SHIFT 305 == CLK_EMMC_PLL_SEL_24M) 306 return DIV_TO_RATE(OSC_HZ, div) / 2; 307 else 308 return DIV_TO_RATE(priv->gpll_hz, div) / 2; 309 } 310 311 static ulong rk3328_mmc_set_clk(struct rk3328_clk_priv *priv, 312 ulong clk_id, ulong set_rate) 313 { 314 struct rk3328_cru *cru = priv->cru; 315 int src_clk_div; 316 u32 con_id; 317 318 switch (clk_id) { 319 case HCLK_SDMMC: 320 case SCLK_SDMMC: 321 con_id = 30; 322 break; 323 case HCLK_EMMC: 324 case SCLK_EMMC: 325 con_id = 32; 326 break; 327 default: 328 return -EINVAL; 329 } 330 /* Select clk_sdmmc/emmc source from GPLL by default */ 331 /* mmc clock defaulg div 2 internal, need provide double in cru */ 332 src_clk_div = DIV_ROUND_UP(priv->gpll_hz / 2, set_rate); 333 334 if (src_clk_div > 127) { 335 /* use 24MHz source for 400KHz clock */ 336 src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, set_rate); 337 rk_clrsetreg(&cru->clksel_con[con_id], 338 CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK, 339 CLK_EMMC_PLL_SEL_24M << CLK_EMMC_PLL_SHIFT | 340 (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT); 341 } else { 342 rk_clrsetreg(&cru->clksel_con[con_id], 343 CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK, 344 CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT | 345 (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT); 346 } 347 348 return rk3328_mmc_get_clk(priv, clk_id); 349 } 350 351 static ulong rk3328_spi_get_clk(struct rk3328_clk_priv *priv) 352 { 353 struct rk3328_cru *cru = priv->cru; 354 u32 div, con, mux, p_rate; 355 356 con = readl(&cru->clksel_con[24]); 357 div = (con & CLK_SPI_DIV_CON_MASK) >> CLK_SPI_DIV_CON_SHIFT; 358 mux = (con & CLK_SPI_PLL_SEL_MASK) >> CLK_SPI_PLL_SEL_SHIFT; 359 if (mux) 360 p_rate = priv->gpll_hz; 361 else 362 p_rate = priv->cpll_hz; 363 364 return DIV_TO_RATE(p_rate, div); 365 } 366 367 static ulong rk3328_spi_set_clk(struct rk3328_clk_priv *priv, uint hz) 368 { 369 struct rk3328_cru *cru = priv->cru; 370 u32 div = priv->gpll_hz / hz; 371 372 rk_clrsetreg(&cru->clksel_con[24], 373 CLK_SPI_PLL_SEL_MASK | CLK_SPI_DIV_CON_MASK, 374 CLK_SPI_PLL_SEL_GPLL << CLK_SPI_PLL_SEL_SHIFT | 375 (div - 1) << CLK_SPI_DIV_CON_SHIFT); 376 377 return DIV_TO_RATE(priv->gpll_hz, div); 378 } 379 380 #ifndef CONFIG_SPL_BUILD 381 static ulong rk3328_pwm_get_clk(struct rk3328_clk_priv *priv) 382 { 383 struct rk3328_cru *cru = priv->cru; 384 u32 div, con; 385 386 con = readl(&cru->clksel_con[24]); 387 div = (con & CLK_PWM_DIV_CON_MASK) >> CLK_PWM_DIV_CON_SHIFT; 388 389 return DIV_TO_RATE(priv->gpll_hz, div); 390 } 391 392 static ulong rk3328_pwm_set_clk(struct rk3328_clk_priv *priv, uint hz) 393 { 394 struct rk3328_cru *cru = priv->cru; 395 u32 div = priv->gpll_hz / hz; 396 397 rk_clrsetreg(&cru->clksel_con[24], 398 CLK_PWM_PLL_SEL_MASK | CLK_PWM_DIV_CON_MASK, 399 CLK_PWM_PLL_SEL_GPLL << CLK_PWM_PLL_SEL_SHIFT | 400 (div - 1) << CLK_PWM_DIV_CON_SHIFT); 401 402 return DIV_TO_RATE(priv->gpll_hz, div); 403 } 404 405 static ulong rk3328_saradc_get_clk(struct rk3328_clk_priv *priv) 406 { 407 struct rk3328_cru *cru = priv->cru; 408 u32 div, val; 409 410 val = readl(&cru->clksel_con[23]); 411 div = bitfield_extract(val, CLK_SARADC_DIV_CON_SHIFT, 412 CLK_SARADC_DIV_CON_WIDTH); 413 414 return DIV_TO_RATE(OSC_HZ, div); 415 } 416 417 static ulong rk3328_saradc_set_clk(struct rk3328_clk_priv *priv, uint hz) 418 { 419 struct rk3328_cru *cru = priv->cru; 420 int src_clk_div; 421 422 src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1; 423 assert(src_clk_div < 128); 424 425 rk_clrsetreg(&cru->clksel_con[23], 426 CLK_SARADC_DIV_CON_MASK, 427 src_clk_div << CLK_SARADC_DIV_CON_SHIFT); 428 429 return rk3328_saradc_get_clk(priv); 430 } 431 432 static ulong rk3328_tsadc_get_clk(struct rk3328_clk_priv *priv) 433 { 434 struct rk3328_cru *cru = priv->cru; 435 u32 div, val; 436 437 val = readl(&cru->clksel_con[22]); 438 div = bitfield_extract(val, CLK_SARADC_DIV_CON_SHIFT, 439 CLK_SARADC_DIV_CON_WIDTH); 440 441 return DIV_TO_RATE(OSC_HZ, div); 442 } 443 444 static ulong rk3328_tsadc_set_clk(struct rk3328_clk_priv *priv, uint hz) 445 { 446 struct rk3328_cru *cru = priv->cru; 447 int src_clk_div; 448 449 src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1; 450 assert(src_clk_div < 128); 451 452 rk_clrsetreg(&cru->clksel_con[22], 453 CLK_SARADC_DIV_CON_MASK, 454 src_clk_div << CLK_SARADC_DIV_CON_SHIFT); 455 456 return rk3328_tsadc_get_clk(priv); 457 } 458 459 static ulong rk3328_vop_get_clk(struct rk3328_clk_priv *priv, ulong clk_id) 460 { 461 struct rk3328_cru *cru = priv->cru; 462 u32 div, con, parent; 463 464 switch (clk_id) { 465 case ACLK_VOP_PRE: 466 case ACLK_VOP: 467 con = readl(&cru->clksel_con[39]); 468 div = (con & ACLK_VOP_DIV_CON_MASK) >> ACLK_VOP_DIV_CON_SHIFT; 469 parent = priv->cpll_hz; 470 break; 471 case ACLK_VIO_PRE: 472 case ACLK_VIO: 473 con = readl(&cru->clksel_con[37]); 474 div = (con & ACLK_VIO_DIV_CON_MASK) >> ACLK_VIO_DIV_CON_SHIFT; 475 parent = priv->cpll_hz; 476 break; 477 case HCLK_VIO_PRE: 478 case HCLK_VIO: 479 parent = rk3328_vop_get_clk(priv, ACLK_VIO_PRE); 480 con = readl(&cru->clksel_con[37]); 481 div = (con & HCLK_VIO_DIV_CON_MASK) >> HCLK_VIO_DIV_CON_SHIFT; 482 break; 483 default: 484 return -ENOENT; 485 } 486 487 return DIV_TO_RATE(parent, div); 488 } 489 490 static ulong rk3328_vop_set_clk(struct rk3328_clk_priv *priv, 491 ulong clk_id, uint hz) 492 { 493 struct rk3328_cru *cru = priv->cru; 494 int src_clk_div; 495 u32 con, parent; 496 497 src_clk_div = DIV_ROUND_UP(priv->cpll_hz, hz); 498 assert(src_clk_div - 1 < 31); 499 500 switch (clk_id) { 501 case ACLK_VOP_PRE: 502 case ACLK_VOP: 503 rk_clrsetreg(&cru->clksel_con[39], 504 ACLK_VOP_PLL_SEL_MASK | ACLK_VOP_DIV_CON_MASK, 505 ACLK_VOP_PLL_SEL_CPLL << ACLK_VOP_PLL_SEL_SHIFT | 506 (src_clk_div - 1) << ACLK_VOP_DIV_CON_SHIFT); 507 break; 508 case ACLK_VIO_PRE: 509 case ACLK_VIO: 510 rk_clrsetreg(&cru->clksel_con[37], 511 ACLK_VIO_PLL_SEL_MASK | ACLK_VIO_DIV_CON_MASK, 512 ACLK_VIO_PLL_SEL_CPLL << ACLK_VIO_PLL_SEL_SHIFT | 513 (src_clk_div - 1) << ACLK_VIO_DIV_CON_SHIFT); 514 break; 515 case HCLK_VIO_PRE: 516 case HCLK_VIO: 517 src_clk_div = DIV_ROUND_UP(rk3328_vop_get_clk(priv, 518 ACLK_VIO_PRE), 519 hz); 520 rk_clrsetreg(&cru->clksel_con[37], 521 HCLK_VIO_DIV_CON_MASK, 522 (src_clk_div - 1) << HCLK_VIO_DIV_CON_SHIFT); 523 break; 524 case DCLK_LCDC: 525 con = readl(&cru->clksel_con[40]); 526 con = (con & DCLK_LCDC_SEL_MASK) >> DCLK_LCDC_SEL_SHIFT; 527 if (con) { 528 parent = readl(&cru->clksel_con[40]); 529 parent = (parent & DCLK_LCDC_PLL_SEL_MASK) >> 530 DCLK_LCDC_PLL_SEL_SHIFT; 531 if (parent) 532 src_clk_div = DIV_ROUND_UP(priv->cpll_hz, hz); 533 else 534 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz); 535 536 rk_clrsetreg(&cru->clksel_con[40], 537 DCLK_LCDC_DIV_CON_MASK, 538 (src_clk_div - 1) << 539 DCLK_LCDC_DIV_CON_SHIFT); 540 } 541 break; 542 default: 543 printf("do not support this vop freq\n"); 544 return -EINVAL; 545 } 546 547 return rk3328_vop_get_clk(priv, clk_id); 548 } 549 #endif 550 551 static ulong rk3328_bus_get_clk(struct rk3328_clk_priv *priv, ulong clk_id) 552 { 553 struct rk3328_cru *cru = priv->cru; 554 u32 div, con, parent; 555 556 switch (clk_id) { 557 case ACLK_BUS_PRE: 558 con = readl(&cru->clksel_con[0]); 559 div = (con & ACLK_BUS_DIV_CON_MASK) >> ACLK_BUS_DIV_CON_SHIFT; 560 parent = priv->cpll_hz; 561 break; 562 case HCLK_BUS_PRE: 563 con = readl(&cru->clksel_con[1]); 564 div = (con & HCLK_BUS_DIV_CON_MASK) >> HCLK_BUS_DIV_CON_SHIFT; 565 parent = rk3328_bus_get_clk(priv, ACLK_BUS_PRE); 566 break; 567 case PCLK_BUS_PRE: 568 con = readl(&cru->clksel_con[1]); 569 div = (con & PCLK_BUS_DIV_CON_MASK) >> PCLK_BUS_DIV_CON_SHIFT; 570 parent = rk3328_bus_get_clk(priv, ACLK_BUS_PRE); 571 break; 572 default: 573 return -ENOENT; 574 } 575 576 return DIV_TO_RATE(parent, div); 577 } 578 579 static ulong rk3328_bus_set_clk(struct rk3328_clk_priv *priv, 580 ulong clk_id, ulong hz) 581 { 582 struct rk3328_cru *cru = priv->cru; 583 int src_clk_div; 584 585 /* 586 * select gpll as pd_bus bus clock source and 587 * set up dependent divisors for PCLK/HCLK and ACLK clocks. 588 */ 589 switch (clk_id) { 590 case ACLK_BUS_PRE: 591 src_clk_div = DIV_ROUND_UP(priv->cpll_hz, hz); 592 assert(src_clk_div - 1 < 31); 593 if (src_clk_div > 32) 594 src_clk_div = 32; 595 rk_clrsetreg(&cru->clksel_con[0], 596 CLK_BUS_PLL_SEL_MASK | ACLK_BUS_DIV_CON_MASK, 597 CLK_BUS_PLL_SEL_CPLL << CLK_BUS_PLL_SEL_SHIFT | 598 (src_clk_div - 1) << ACLK_BUS_DIV_CON_SHIFT); 599 break; 600 case HCLK_BUS_PRE: 601 src_clk_div = DIV_ROUND_UP(rk3328_bus_get_clk(priv, 602 ACLK_BUS_PRE), 603 hz); 604 assert(src_clk_div - 1 < 3); 605 rk_clrsetreg(&cru->clksel_con[1], 606 HCLK_BUS_DIV_CON_MASK, 607 (src_clk_div - 1) << HCLK_BUS_DIV_CON_SHIFT); 608 break; 609 case PCLK_BUS_PRE: 610 src_clk_div = DIV_ROUND_UP(rk3328_bus_get_clk(priv, 611 ACLK_BUS_PRE), 612 hz); 613 assert(src_clk_div - 1 < 7); 614 rk_clrsetreg(&cru->clksel_con[1], 615 PCLK_BUS_DIV_CON_MASK, 616 (src_clk_div - 1) << PCLK_BUS_DIV_CON_SHIFT); 617 break; 618 default: 619 printf("do not support this bus freq\n"); 620 return -EINVAL; 621 } 622 return rk3328_bus_get_clk(priv, clk_id); 623 } 624 625 static ulong rk3328_peri_get_clk(struct rk3328_clk_priv *priv, ulong clk_id) 626 { 627 struct rk3328_cru *cru = priv->cru; 628 u32 div, con, parent; 629 630 switch (clk_id) { 631 case ACLK_PERI_PRE: 632 con = readl(&cru->clksel_con[28]); 633 div = (con & ACLK_PERI_DIV_CON_MASK) >> ACLK_PERI_DIV_CON_SHIFT; 634 parent = priv->cpll_hz; 635 break; 636 case HCLK_PERI: 637 con = readl(&cru->clksel_con[29]); 638 div = (con & HCLK_PERI_DIV_CON_MASK) >> HCLK_PERI_DIV_CON_SHIFT; 639 parent = rk3328_peri_get_clk(priv, ACLK_PERI_PRE); 640 break; 641 case PCLK_PERI: 642 con = readl(&cru->clksel_con[29]); 643 div = (con & PCLK_PERI_DIV_CON_MASK) >> PCLK_PERI_DIV_CON_SHIFT; 644 parent = rk3328_peri_get_clk(priv, ACLK_PERI_PRE); 645 break; 646 default: 647 return -ENOENT; 648 } 649 650 return DIV_TO_RATE(parent, div); 651 } 652 653 static ulong rk3328_peri_set_clk(struct rk3328_clk_priv *priv, 654 ulong clk_id, ulong hz) 655 { 656 struct rk3328_cru *cru = priv->cru; 657 int src_clk_div; 658 659 /* 660 * select gpll as pd_bus bus clock source and 661 * set up dependent divisors for PCLK/HCLK and ACLK clocks. 662 */ 663 switch (clk_id) { 664 case ACLK_PERI_PRE: 665 src_clk_div = DIV_ROUND_UP(priv->cpll_hz, hz); 666 assert(src_clk_div - 1 < 31); 667 if (src_clk_div > 32) 668 src_clk_div = 32; 669 rk_clrsetreg(&cru->clksel_con[28], 670 CLK_PERI_PLL_SEL_MASK | ACLK_PERI_DIV_CON_MASK, 671 CLK_PERI_PLL_SEL_CPLL << CLK_PERI_PLL_SEL_SHIFT | 672 (src_clk_div - 1) << ACLK_PERI_DIV_CON_SHIFT); 673 break; 674 case HCLK_PERI: 675 src_clk_div = DIV_ROUND_UP(rk3328_peri_get_clk(priv, 676 ACLK_PERI_PRE), 677 hz); 678 assert(src_clk_div - 1 < 3); 679 rk_clrsetreg(&cru->clksel_con[29], 680 HCLK_PERI_DIV_CON_MASK, 681 (src_clk_div - 1) << HCLK_PERI_DIV_CON_SHIFT); 682 break; 683 case PCLK_PERI: 684 src_clk_div = DIV_ROUND_UP(rk3328_peri_get_clk(priv, 685 ACLK_PERI_PRE), 686 hz); 687 assert(src_clk_div - 1 < 7); 688 rk_clrsetreg(&cru->clksel_con[29], 689 PCLK_PERI_DIV_CON_MASK, 690 (src_clk_div - 1) << PCLK_PERI_DIV_CON_SHIFT); 691 break; 692 default: 693 printf("do not support this bus freq\n"); 694 return -EINVAL; 695 } 696 697 return rk3328_peri_get_clk(priv, clk_id); 698 } 699 700 #ifndef CONFIG_SPL_BUILD 701 static ulong rk3328_crypto_get_clk(struct rk3328_clk_priv *priv, ulong clk_id) 702 { 703 struct rk3328_cru *cru = priv->cru; 704 u32 div, con, parent; 705 706 switch (clk_id) { 707 case SCLK_CRYPTO: 708 con = readl(&cru->clksel_con[20]); 709 div = (con & CRYPTO_DIV_MASK) >> CRYPTO_DIV_SHIFT; 710 parent = priv->gpll_hz; 711 break; 712 default: 713 return -ENOENT; 714 } 715 716 return DIV_TO_RATE(parent, div); 717 } 718 719 static ulong rk3328_crypto_set_clk(struct rk3328_clk_priv *priv, ulong clk_id, 720 ulong hz) 721 { 722 struct rk3328_cru *cru = priv->cru; 723 int src_clk_div; 724 725 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz); 726 assert(src_clk_div - 1 <= 127); 727 728 /* 729 * select gpll as crypto clock source and 730 * set up dependent divisors for crypto clocks. 731 */ 732 switch (clk_id) { 733 case SCLK_CRYPTO: 734 rk_clrsetreg(&cru->clksel_con[20], 735 CRYPTO_PLL_SEL_MASK | CRYPTO_DIV_MASK, 736 CRYPTO_PLL_SEL_GPLL << CRYPTO_PLL_SEL_SHIFT | 737 (src_clk_div - 1) << CRYPTO_DIV_SHIFT); 738 break; 739 default: 740 printf("do not support this peri freq\n"); 741 return -EINVAL; 742 } 743 744 return rk3328_crypto_get_clk(priv, clk_id); 745 } 746 #endif 747 748 static ulong rk3328_clk_get_rate(struct clk *clk) 749 { 750 struct rk3328_clk_priv *priv = dev_get_priv(clk->dev); 751 ulong rate = 0; 752 753 #ifndef CONFIG_SPL_BUILD 754 if (!priv->gpll_hz) { 755 priv->gpll_hz = rockchip_pll_get_rate(&rk3328_pll_clks[GPLL], 756 priv->cru, GPLL); 757 debug("%s gpll=%lu\n", __func__, priv->gpll_hz); 758 } 759 if (!priv->cpll_hz) { 760 priv->cpll_hz = rockchip_pll_get_rate(&rk3328_pll_clks[CPLL], 761 priv->cru, CPLL); 762 debug("%s cpll=%lu\n", __func__, priv->cpll_hz); 763 } 764 #endif 765 766 switch (clk->id) { 767 case PLL_APLL: 768 case PLL_DPLL: 769 case PLL_CPLL: 770 case PLL_GPLL: 771 case PLL_NPLL: 772 rate = rockchip_pll_get_rate(&rk3328_pll_clks[clk->id - 1], 773 priv->cru, clk->id - 1); 774 break; 775 case ARMCLK: 776 rate = rockchip_pll_get_rate(&rk3328_pll_clks[NPLL], 777 priv->cru, NPLL); 778 break; 779 case ACLK_BUS_PRE: 780 case HCLK_BUS_PRE: 781 case PCLK_BUS_PRE: 782 rate = rk3328_bus_get_clk(priv, clk->id); 783 break; 784 case ACLK_PERI_PRE: 785 case HCLK_PERI: 786 case PCLK_PERI: 787 rate = rk3328_peri_get_clk(priv, clk->id); 788 break; 789 case HCLK_SDMMC: 790 case HCLK_EMMC: 791 case SCLK_SDMMC: 792 case SCLK_EMMC: 793 case SCLK_EMMC_SAMPLE: 794 rate = rk3328_mmc_get_clk(priv, clk->id); 795 break; 796 case SCLK_SPI: 797 rate = rk3328_spi_get_clk(priv); 798 break; 799 #ifndef CONFIG_SPL_BUILD 800 case SCLK_I2C0: 801 case SCLK_I2C1: 802 case SCLK_I2C2: 803 case SCLK_I2C3: 804 rate = rk3328_i2c_get_clk(priv, clk->id); 805 break; 806 case SCLK_PWM: 807 rate = rk3328_pwm_get_clk(priv); 808 break; 809 case SCLK_SARADC: 810 rate = rk3328_saradc_get_clk(priv); 811 break; 812 case SCLK_TSADC: 813 rate = rk3328_tsadc_get_clk(priv); 814 break; 815 case ACLK_VOP_PRE: 816 case ACLK_VIO_PRE: 817 case HCLK_VIO_PRE: 818 case ACLK_VOP: 819 case ACLK_VIO: 820 case HCLK_VIO: 821 rate = rk3328_vop_get_clk(priv, clk->id); 822 break; 823 case SCLK_CRYPTO: 824 rate = rk3328_crypto_get_clk(priv, clk->id); 825 break; 826 #endif 827 default: 828 return -ENOENT; 829 } 830 831 return rate; 832 } 833 834 static ulong rk3328_clk_set_rate(struct clk *clk, ulong rate) 835 { 836 struct rk3328_clk_priv *priv = dev_get_priv(clk->dev); 837 ulong ret = 0; 838 839 switch (clk->id) { 840 case PLL_APLL: 841 case PLL_DPLL: 842 case PLL_NPLL: 843 ret = rockchip_pll_set_rate(&rk3328_pll_clks[clk->id - 1], 844 priv->cru, clk->id - 1, rate); 845 break; 846 case PLL_CPLL: 847 ret = rockchip_pll_set_rate(&rk3328_pll_clks[CPLL], 848 priv->cru, CPLL, rate); 849 priv->cpll_hz = rate; 850 break; 851 case PLL_GPLL: 852 ret = rockchip_pll_set_rate(&rk3328_pll_clks[GPLL], 853 priv->cru, GPLL, rate); 854 priv->gpll_hz = rate; 855 break; 856 case ARMCLK: 857 if (priv->armclk_hz) 858 ret = rk3328_armclk_set_clk(priv, rate); 859 priv->armclk_hz = rate; 860 break; 861 case ACLK_BUS_PRE: 862 case HCLK_BUS_PRE: 863 case PCLK_BUS_PRE: 864 rate = rk3328_bus_set_clk(priv, clk->id, rate); 865 break; 866 case ACLK_PERI_PRE: 867 case HCLK_PERI: 868 case PCLK_PERI: 869 rate = rk3328_peri_set_clk(priv, clk->id, rate); 870 break; 871 case HCLK_SDMMC: 872 case HCLK_EMMC: 873 case SCLK_SDMMC: 874 case SCLK_EMMC: 875 ret = rk3328_mmc_set_clk(priv, clk->id, rate); 876 break; 877 case SCLK_SPI: 878 ret = rk3328_spi_set_clk(priv, rate); 879 break; 880 #ifndef CONFIG_SPL_BUILD 881 case SCLK_I2C0: 882 case SCLK_I2C1: 883 case SCLK_I2C2: 884 case SCLK_I2C3: 885 ret = rk3328_i2c_set_clk(priv, clk->id, rate); 886 break; 887 case SCLK_MAC2IO: 888 ret = rk3328_gmac2io_set_clk(priv, rate); 889 break; 890 case SCLK_PWM: 891 ret = rk3328_pwm_set_clk(priv, rate); 892 break; 893 case SCLK_SARADC: 894 ret = rk3328_saradc_set_clk(priv, rate); 895 break; 896 case SCLK_TSADC: 897 ret = rk3328_tsadc_set_clk(priv, rate); 898 break; 899 case DCLK_LCDC: 900 case ACLK_VOP_PRE: 901 case ACLK_VIO_PRE: 902 case HCLK_VIO_PRE: 903 case ACLK_VOP: 904 case ACLK_VIO: 905 case HCLK_VIO: 906 rate = rk3328_vop_set_clk(priv, clk->id, rate); 907 break; 908 case SCLK_CRYPTO: 909 rate = rk3328_crypto_set_clk(priv, clk->id, rate); 910 break; 911 #endif 912 case SCLK_PDM: 913 case SCLK_RTC32K: 914 case SCLK_UART0: 915 case SCLK_UART1: 916 case SCLK_UART2: 917 case SCLK_SDIO: 918 case SCLK_TSP: 919 case SCLK_WIFI: 920 case ACLK_RGA_PRE: 921 case SCLK_RGA: 922 case ACLK_RKVDEC_PRE: 923 case ACLK_RKVENC: 924 case ACLK_VPU_PRE: 925 case SCLK_VDEC_CABAC: 926 case SCLK_VDEC_CORE: 927 case SCLK_VENC_CORE: 928 case SCLK_VENC_DSP: 929 case SCLK_EFUSE: 930 case PCLK_DDR: 931 case ACLK_GMAC: 932 case PCLK_GMAC: 933 case SCLK_USB3OTG_SUSPEND: 934 return 0; 935 default: 936 return -ENOENT; 937 } 938 939 return ret; 940 } 941 942 #ifndef CONFIG_SPL_BUILD 943 static int rk3328_gmac2io_set_parent(struct clk *clk, struct clk *parent) 944 { 945 struct rk3328_grf_regs *grf; 946 const char *clock_output_name; 947 int ret; 948 949 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 950 951 /* 952 * If the requested parent is in the same clock-controller and the id 953 * is SCLK_MAC2IO_SRC ("clk_mac2io_src"), switch to the internal clock. 954 */ 955 if ((parent->dev == clk->dev) && (parent->id == SCLK_MAC2IO_SRC)) { 956 debug("%s: switching RGMII to SCLK_MAC2IO_SRC\n", __func__); 957 rk_clrreg(&grf->mac_con[1], BIT(10)); 958 return 0; 959 } 960 961 /* 962 * Otherwise, we need to check the clock-output-names of the 963 * requested parent to see if the requested id is "gmac_clkin". 964 */ 965 ret = dev_read_string_index(parent->dev, "clock-output-names", 966 parent->id, &clock_output_name); 967 if (ret < 0) 968 return -ENODATA; 969 970 /* If this is "gmac_clkin", switch to the external clock input */ 971 if (!strcmp(clock_output_name, "gmac_clkin")) { 972 debug("%s: switching RGMII to CLKIN\n", __func__); 973 rk_setreg(&grf->mac_con[1], BIT(10)); 974 return 0; 975 } 976 977 return -EINVAL; 978 } 979 980 static int rk3328_gmac2io_ext_set_parent(struct clk *clk, struct clk *parent) 981 { 982 struct rk3328_grf_regs *grf; 983 const char *clock_output_name; 984 int ret; 985 986 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 987 988 /* 989 * If the requested parent is in the same clock-controller and the id 990 * is SCLK_MAC2IO ("clk_mac2io"), switch to the internal clock. 991 */ 992 if ((parent->dev == clk->dev) && (parent->id == SCLK_MAC2IO)) { 993 debug("%s: switching RGMII to SCLK_MAC2IO\n", __func__); 994 rk_clrreg(&grf->soc_con[4], BIT(14)); 995 return 0; 996 } 997 998 /* 999 * Otherwise, we need to check the clock-output-names of the 1000 * requested parent to see if the requested id is "gmac_clkin". 1001 */ 1002 ret = dev_read_string_index(parent->dev, "clock-output-names", 1003 parent->id, &clock_output_name); 1004 if (ret < 0) 1005 return -ENODATA; 1006 1007 /* If this is "gmac_clkin", switch to the external clock input */ 1008 if (!strcmp(clock_output_name, "gmac_clkin")) { 1009 debug("%s: switching RGMII to CLKIN\n", __func__); 1010 rk_setreg(&grf->soc_con[4], BIT(14)); 1011 return 0; 1012 } 1013 1014 return -EINVAL; 1015 } 1016 1017 static int rk3328_lcdc_set_parent(struct clk *clk, struct clk *parent) 1018 { 1019 struct rk3328_clk_priv *priv = dev_get_priv(clk->dev); 1020 1021 if (parent->id == HDMIPHY) 1022 rk_clrsetreg(&priv->cru->clksel_con[40], 1023 DCLK_LCDC_SEL_MASK, 1024 DCLK_LCDC_SEL_HDMIPHY << DCLK_LCDC_SEL_SHIFT); 1025 else if (parent->id == PLL_CPLL) 1026 rk_clrsetreg(&priv->cru->clksel_con[40], 1027 DCLK_LCDC_SEL_MASK | DCLK_LCDC_PLL_SEL_MASK, 1028 (DCLK_LCDC_SEL_PLL << DCLK_LCDC_SEL_SHIFT) | 1029 (DCLK_LCDC_PLL_SEL_CPLL << 1030 DCLK_LCDC_PLL_SEL_SHIFT)); 1031 else 1032 rk_clrsetreg(&priv->cru->clksel_con[40], 1033 DCLK_LCDC_SEL_MASK | DCLK_LCDC_PLL_SEL_MASK, 1034 (DCLK_LCDC_SEL_PLL << DCLK_LCDC_SEL_SHIFT) | 1035 (DCLK_LCDC_PLL_SEL_GPLL << 1036 DCLK_LCDC_PLL_SEL_SHIFT)); 1037 1038 return 0; 1039 } 1040 #endif 1041 1042 static int rk3328_clk_set_parent(struct clk *clk, struct clk *parent) 1043 { 1044 switch (clk->id) { 1045 #ifndef CONFIG_SPL_BUILD 1046 case SCLK_MAC2IO: 1047 return rk3328_gmac2io_set_parent(clk, parent); 1048 case SCLK_MAC2IO_EXT: 1049 return rk3328_gmac2io_ext_set_parent(clk, parent); 1050 case DCLK_LCDC: 1051 return rk3328_lcdc_set_parent(clk, parent); 1052 #endif 1053 case SCLK_PDM: 1054 case SCLK_RTC32K: 1055 case SCLK_UART0: 1056 case SCLK_UART1: 1057 case SCLK_UART2: 1058 return 0; 1059 } 1060 1061 debug("%s: unsupported clk %ld\n", __func__, clk->id); 1062 return -ENOENT; 1063 } 1064 1065 #define ROCKCHIP_MMC_DELAY_SEL BIT(10) 1066 #define ROCKCHIP_MMC_DEGREE_MASK 0x3 1067 #define ROCKCHIP_MMC_DELAYNUM_OFFSET 2 1068 #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET) 1069 1070 #define PSECS_PER_SEC 1000000000000LL 1071 /* 1072 * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to 1073 * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg. 1074 */ 1075 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60 1076 1077 int rk3328_mmc_get_phase(struct clk *clk) 1078 { 1079 struct rk3328_clk_priv *priv = dev_get_priv(clk->dev); 1080 struct rk3328_cru *cru = priv->cru; 1081 u32 raw_value, delay_num; 1082 u16 degrees = 0; 1083 ulong rate; 1084 1085 rate = rk3328_clk_get_rate(clk); 1086 1087 if (rate < 0) 1088 return rate; 1089 1090 if (clk->id == SCLK_EMMC_SAMPLE) 1091 raw_value = readl(&cru->emmc_con[1]); 1092 else if (clk->id == SCLK_SDMMC_SAMPLE) 1093 raw_value = readl(&cru->sdmmc_con[1]); 1094 else 1095 raw_value = readl(&cru->sdio_con[1]); 1096 1097 raw_value >>= 1; 1098 degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90; 1099 1100 if (raw_value & ROCKCHIP_MMC_DELAY_SEL) { 1101 /* degrees/delaynum * 10000 */ 1102 unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) * 1103 36 * (rate / 1000000); 1104 1105 delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK); 1106 delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET; 1107 degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000); 1108 } 1109 1110 return degrees % 360; 1111 } 1112 1113 int rk3328_mmc_set_phase(struct clk *clk, u32 degrees) 1114 { 1115 struct rk3328_clk_priv *priv = dev_get_priv(clk->dev); 1116 struct rk3328_cru *cru = priv->cru; 1117 u8 nineties, remainder, delay_num; 1118 u32 raw_value, delay; 1119 ulong rate; 1120 1121 rate = rk3328_clk_get_rate(clk); 1122 1123 if (rate < 0) 1124 return rate; 1125 1126 nineties = degrees / 90; 1127 remainder = (degrees % 90); 1128 1129 /* 1130 * Convert to delay; do a little extra work to make sure we 1131 * don't overflow 32-bit / 64-bit numbers. 1132 */ 1133 delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */ 1134 delay *= remainder; 1135 delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 * 1136 (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10)); 1137 1138 delay_num = (u8)min_t(u32, delay, 255); 1139 1140 raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0; 1141 raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET; 1142 raw_value |= nineties; 1143 1144 raw_value <<= 1; 1145 if (clk->id == SCLK_EMMC_SAMPLE) 1146 writel(raw_value | 0xffff0000, &cru->emmc_con[1]); 1147 else if (clk->id == SCLK_SDMMC_SAMPLE) 1148 writel(raw_value | 0xffff0000, &cru->sdmmc_con[1]); 1149 else 1150 writel(raw_value | 0xffff0000, &cru->sdio_con[1]); 1151 1152 debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n", 1153 degrees, delay_num, raw_value, rk3328_mmc_get_phase(clk)); 1154 1155 return 0; 1156 } 1157 1158 static int rk3328_clk_get_phase(struct clk *clk) 1159 { 1160 int ret; 1161 1162 debug("%s %ld\n", __func__, clk->id); 1163 switch (clk->id) { 1164 case SCLK_EMMC_SAMPLE: 1165 case SCLK_SDMMC_SAMPLE: 1166 case SCLK_SDIO_SAMPLE: 1167 ret = rk3328_mmc_get_phase(clk); 1168 break; 1169 default: 1170 return -ENOENT; 1171 } 1172 1173 return ret; 1174 } 1175 1176 static int rk3328_clk_set_phase(struct clk *clk, int degrees) 1177 { 1178 int ret; 1179 1180 debug("%s %ld\n", __func__, clk->id); 1181 switch (clk->id) { 1182 case SCLK_EMMC_SAMPLE: 1183 case SCLK_SDMMC_SAMPLE: 1184 case SCLK_SDIO_SAMPLE: 1185 ret = rk3328_mmc_set_phase(clk, degrees); 1186 break; 1187 default: 1188 return -ENOENT; 1189 } 1190 1191 return ret; 1192 } 1193 1194 static struct clk_ops rk3328_clk_ops = { 1195 .get_rate = rk3328_clk_get_rate, 1196 .set_rate = rk3328_clk_set_rate, 1197 .set_parent = rk3328_clk_set_parent, 1198 .get_phase = rk3328_clk_get_phase, 1199 .set_phase = rk3328_clk_set_phase, 1200 }; 1201 1202 static void rkclk_init(struct rk3328_clk_priv *priv) 1203 { 1204 if (rockchip_pll_get_rate(&rk3328_pll_clks[NPLL], 1205 priv->cru, NPLL) != APLL_HZ) 1206 rk3328_armclk_set_clk(priv, APLL_HZ); 1207 1208 priv->gpll_hz = rockchip_pll_get_rate(&rk3328_pll_clks[GPLL], 1209 priv->cru, GPLL); 1210 priv->cpll_hz = rockchip_pll_get_rate(&rk3328_pll_clks[CPLL], 1211 priv->cru, CPLL); 1212 1213 /* before set pll set child div first */ 1214 rk_clrsetreg(&priv->cru->clksel_con[24], (0x3f << 8) | (0x3f << 0), 1215 (0x17 << 8) | (0x17 << 0)); 1216 rk_clrsetreg(&priv->cru->clksel_con[27], (0x1f << 8) | (0x1f << 0), 1217 (0x17 << 8) | (0x17 << 0)); 1218 rk_clrsetreg(&priv->cru->clksel_con[31], 0xff << 0, 0xb << 0); 1219 rk_clrsetreg(&priv->cru->clksel_con[43], 0xff << 0, 0xb << 0); 1220 rk_clrsetreg(&priv->cru->clksel_con[52], 0x1f << 8, 0x5 << 8); 1221 1222 rockchip_pll_set_rate(&rk3328_pll_clks[GPLL], 1223 priv->cru, GPLL, GPLL_HZ); 1224 priv->gpll_hz = GPLL_HZ; 1225 1226 rockchip_pll_set_rate(&rk3328_pll_clks[CPLL], 1227 priv->cru, CPLL, CPLL_HZ); 1228 priv->cpll_hz = CPLL_HZ; 1229 1230 rk3328_bus_set_clk(priv, ACLK_BUS_PRE, ACLK_BUS_HZ); 1231 rk3328_bus_set_clk(priv, HCLK_BUS_PRE, ACLK_BUS_HZ / 2); 1232 rk3328_bus_set_clk(priv, PCLK_BUS_PRE, ACLK_BUS_HZ / 2); 1233 rk3328_peri_set_clk(priv, ACLK_PERI_PRE, ACLK_PERI_HZ); 1234 rk3328_peri_set_clk(priv, HCLK_PERI, ACLK_PERI_HZ / 2); 1235 rk3328_peri_set_clk(priv, PCLK_PERI, ACLK_PERI_HZ / 2); 1236 /*rk3328_mmc_set_clk(priv, SCLK_EMMC, rate);*/ 1237 1238 /* set usbphy and hdmiphy from phy */ 1239 rk_clrsetreg(&priv->cru->misc, (0x1 << 13) | 1240 (0x1 << 15), (0 << 15) | (0 << 13)); 1241 } 1242 1243 static int rk3328_clk_probe(struct udevice *dev) 1244 { 1245 struct rk3328_clk_priv *priv = dev_get_priv(dev); 1246 int ret = 0; 1247 1248 priv->sync_kernel = false; 1249 if (!priv->armclk_enter_hz) 1250 priv->armclk_enter_hz = 1251 rockchip_pll_get_rate(&rk3328_pll_clks[NPLL], 1252 priv->cru, NPLL); 1253 rkclk_init(priv); 1254 if (!priv->armclk_init_hz) 1255 priv->armclk_init_hz = 1256 rockchip_pll_get_rate(&rk3328_pll_clks[NPLL], 1257 priv->cru, NPLL); 1258 1259 ret = clk_set_defaults(dev); 1260 if (ret) 1261 debug("%s clk_set_defaults failed %d\n", __func__, ret); 1262 else 1263 priv->sync_kernel = true; 1264 1265 return 0; 1266 } 1267 1268 static int rk3328_clk_ofdata_to_platdata(struct udevice *dev) 1269 { 1270 struct rk3328_clk_priv *priv = dev_get_priv(dev); 1271 1272 priv->cru = dev_read_addr_ptr(dev); 1273 1274 return 0; 1275 } 1276 1277 static int rk3328_clk_bind(struct udevice *dev) 1278 { 1279 int ret; 1280 struct udevice *sys_child, *sf_child; 1281 struct sysreset_reg *priv; 1282 struct softreset_reg *sf_priv; 1283 1284 /* The reset driver does not have a device node, so bind it here */ 1285 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset", 1286 &sys_child); 1287 if (ret) { 1288 debug("Warning: No sysreset driver: ret=%d\n", ret); 1289 } else { 1290 priv = malloc(sizeof(struct sysreset_reg)); 1291 priv->glb_srst_fst_value = offsetof(struct rk3328_cru, 1292 glb_srst_fst_value); 1293 priv->glb_srst_snd_value = offsetof(struct rk3328_cru, 1294 glb_srst_snd_value); 1295 sys_child->priv = priv; 1296 } 1297 1298 ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset", 1299 dev_ofnode(dev), &sf_child); 1300 if (ret) { 1301 debug("Warning: No rockchip reset driver: ret=%d\n", ret); 1302 } else { 1303 sf_priv = malloc(sizeof(struct softreset_reg)); 1304 sf_priv->sf_reset_offset = offsetof(struct rk3328_cru, 1305 softrst_con[0]); 1306 sf_priv->sf_reset_num = 12; 1307 sf_child->priv = sf_priv; 1308 } 1309 1310 return 0; 1311 } 1312 1313 static const struct udevice_id rk3328_clk_ids[] = { 1314 { .compatible = "rockchip,rk3328-cru" }, 1315 { } 1316 }; 1317 1318 U_BOOT_DRIVER(rockchip_rk3328_cru) = { 1319 .name = "rockchip_rk3328_cru", 1320 .id = UCLASS_CLK, 1321 .of_match = rk3328_clk_ids, 1322 .priv_auto_alloc_size = sizeof(struct rk3328_clk_priv), 1323 .ofdata_to_platdata = rk3328_clk_ofdata_to_platdata, 1324 .ops = &rk3328_clk_ops, 1325 .bind = rk3328_clk_bind, 1326 .probe = rk3328_clk_probe, 1327 }; 1328 1329 #ifndef CONFIG_SPL_BUILD 1330 /** 1331 * soc_clk_dump() - Print clock frequencies 1332 * Returns zero on success 1333 * 1334 * Implementation for the clk dump command. 1335 */ 1336 int soc_clk_dump(void) 1337 { 1338 struct udevice *cru_dev; 1339 struct rk3328_clk_priv *priv; 1340 const struct rk3328_clk_info *clk_dump; 1341 struct clk clk; 1342 unsigned long clk_count = ARRAY_SIZE(clks_dump); 1343 unsigned long rate; 1344 int i, ret; 1345 1346 ret = uclass_get_device_by_driver(UCLASS_CLK, 1347 DM_GET_DRIVER(rockchip_rk3328_cru), 1348 &cru_dev); 1349 if (ret) { 1350 printf("%s failed to get cru device\n", __func__); 1351 return ret; 1352 } 1353 1354 priv = dev_get_priv(cru_dev); 1355 printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n", 1356 priv->sync_kernel ? "sync kernel" : "uboot", 1357 priv->armclk_enter_hz / 1000, 1358 priv->armclk_init_hz / 1000, 1359 priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0, 1360 priv->set_armclk_rate ? " KHz" : "N/A"); 1361 for (i = 0; i < clk_count; i++) { 1362 clk_dump = &clks_dump[i]; 1363 if (clk_dump->name) { 1364 clk.id = clk_dump->id; 1365 if (clk_dump->is_cru) 1366 ret = clk_request(cru_dev, &clk); 1367 if (ret < 0) 1368 return ret; 1369 1370 rate = clk_get_rate(&clk); 1371 clk_free(&clk); 1372 if (i == 0) { 1373 if (rate < 0) 1374 printf(" %s %s\n", clk_dump->name, 1375 "unknown"); 1376 else 1377 printf(" %s %lu KHz\n", clk_dump->name, 1378 rate / 1000); 1379 } else { 1380 if (rate < 0) 1381 printf(" %s %s\n", clk_dump->name, 1382 "unknown"); 1383 else 1384 printf(" %s %lu KHz\n", clk_dump->name, 1385 rate / 1000); 1386 } 1387 } 1388 } 1389 1390 return 0; 1391 } 1392 #endif 1393