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 rk_clrsetreg(&cru->clksel_con[0], 594 CLK_BUS_PLL_SEL_MASK | ACLK_BUS_DIV_CON_MASK, 595 CLK_BUS_PLL_SEL_CPLL << CLK_BUS_PLL_SEL_SHIFT | 596 (src_clk_div - 1) << ACLK_BUS_DIV_CON_SHIFT); 597 break; 598 case HCLK_BUS_PRE: 599 src_clk_div = DIV_ROUND_UP(rk3328_bus_get_clk(priv, 600 ACLK_BUS_PRE), 601 hz); 602 assert(src_clk_div - 1 < 3); 603 rk_clrsetreg(&cru->clksel_con[1], 604 HCLK_BUS_DIV_CON_MASK, 605 (src_clk_div - 1) << HCLK_BUS_DIV_CON_SHIFT); 606 break; 607 case PCLK_BUS_PRE: 608 src_clk_div = DIV_ROUND_UP(rk3328_bus_get_clk(priv, 609 ACLK_BUS_PRE), 610 hz); 611 assert(src_clk_div - 1 < 7); 612 rk_clrsetreg(&cru->clksel_con[1], 613 PCLK_BUS_DIV_CON_MASK, 614 (src_clk_div - 1) << PCLK_BUS_DIV_CON_SHIFT); 615 break; 616 default: 617 printf("do not support this bus freq\n"); 618 return -EINVAL; 619 } 620 return rk3328_bus_get_clk(priv, clk_id); 621 } 622 623 static ulong rk3328_peri_get_clk(struct rk3328_clk_priv *priv, ulong clk_id) 624 { 625 struct rk3328_cru *cru = priv->cru; 626 u32 div, con, parent; 627 628 switch (clk_id) { 629 case ACLK_PERI_PRE: 630 con = readl(&cru->clksel_con[28]); 631 div = (con & ACLK_PERI_DIV_CON_MASK) >> ACLK_PERI_DIV_CON_SHIFT; 632 parent = priv->cpll_hz; 633 break; 634 case HCLK_PERI: 635 con = readl(&cru->clksel_con[29]); 636 div = (con & HCLK_PERI_DIV_CON_MASK) >> HCLK_PERI_DIV_CON_SHIFT; 637 parent = rk3328_peri_get_clk(priv, ACLK_PERI_PRE); 638 break; 639 case PCLK_PERI: 640 con = readl(&cru->clksel_con[29]); 641 div = (con & PCLK_PERI_DIV_CON_MASK) >> PCLK_PERI_DIV_CON_SHIFT; 642 parent = rk3328_peri_get_clk(priv, ACLK_PERI_PRE); 643 break; 644 default: 645 return -ENOENT; 646 } 647 648 return DIV_TO_RATE(parent, div); 649 } 650 651 static ulong rk3328_peri_set_clk(struct rk3328_clk_priv *priv, 652 ulong clk_id, ulong hz) 653 { 654 struct rk3328_cru *cru = priv->cru; 655 int src_clk_div; 656 657 /* 658 * select gpll as pd_bus bus clock source and 659 * set up dependent divisors for PCLK/HCLK and ACLK clocks. 660 */ 661 switch (clk_id) { 662 case ACLK_PERI_PRE: 663 src_clk_div = DIV_ROUND_UP(priv->cpll_hz, hz); 664 assert(src_clk_div - 1 < 31); 665 rk_clrsetreg(&cru->clksel_con[28], 666 CLK_PERI_PLL_SEL_MASK | ACLK_PERI_DIV_CON_MASK, 667 CLK_PERI_PLL_SEL_CPLL << CLK_PERI_PLL_SEL_SHIFT | 668 (src_clk_div - 1) << ACLK_PERI_DIV_CON_SHIFT); 669 break; 670 case HCLK_PERI: 671 src_clk_div = DIV_ROUND_UP(rk3328_peri_get_clk(priv, 672 ACLK_PERI_PRE), 673 hz); 674 assert(src_clk_div - 1 < 3); 675 rk_clrsetreg(&cru->clksel_con[29], 676 HCLK_PERI_DIV_CON_MASK, 677 (src_clk_div - 1) << HCLK_PERI_DIV_CON_SHIFT); 678 break; 679 case PCLK_PERI: 680 src_clk_div = DIV_ROUND_UP(rk3328_peri_get_clk(priv, 681 ACLK_PERI_PRE), 682 hz); 683 assert(src_clk_div - 1 < 7); 684 rk_clrsetreg(&cru->clksel_con[29], 685 PCLK_PERI_DIV_CON_MASK, 686 (src_clk_div - 1) << PCLK_PERI_DIV_CON_SHIFT); 687 break; 688 default: 689 printf("do not support this bus freq\n"); 690 return -EINVAL; 691 } 692 693 return rk3328_peri_get_clk(priv, clk_id); 694 } 695 696 #ifndef CONFIG_SPL_BUILD 697 static ulong rk3328_crypto_get_clk(struct rk3328_clk_priv *priv, ulong clk_id) 698 { 699 struct rk3328_cru *cru = priv->cru; 700 u32 div, con, parent; 701 702 switch (clk_id) { 703 case SCLK_CRYPTO: 704 con = readl(&cru->clksel_con[20]); 705 div = (con & CRYPTO_DIV_MASK) >> CRYPTO_DIV_SHIFT; 706 parent = priv->gpll_hz; 707 break; 708 default: 709 return -ENOENT; 710 } 711 712 return DIV_TO_RATE(parent, div); 713 } 714 715 static ulong rk3328_crypto_set_clk(struct rk3328_clk_priv *priv, ulong clk_id, 716 ulong hz) 717 { 718 struct rk3328_cru *cru = priv->cru; 719 int src_clk_div; 720 721 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz); 722 assert(src_clk_div - 1 <= 127); 723 724 /* 725 * select gpll as crypto clock source and 726 * set up dependent divisors for crypto clocks. 727 */ 728 switch (clk_id) { 729 case SCLK_CRYPTO: 730 rk_clrsetreg(&cru->clksel_con[20], 731 CRYPTO_PLL_SEL_MASK | CRYPTO_DIV_MASK, 732 CRYPTO_PLL_SEL_GPLL << CRYPTO_PLL_SEL_SHIFT | 733 (src_clk_div - 1) << CRYPTO_DIV_SHIFT); 734 break; 735 default: 736 printf("do not support this peri freq\n"); 737 return -EINVAL; 738 } 739 740 return rk3328_crypto_get_clk(priv, clk_id); 741 } 742 #endif 743 744 static ulong rk3328_clk_get_rate(struct clk *clk) 745 { 746 struct rk3328_clk_priv *priv = dev_get_priv(clk->dev); 747 ulong rate = 0; 748 749 #ifndef CONFIG_SPL_BUILD 750 if (!priv->gpll_hz) { 751 priv->gpll_hz = rockchip_pll_get_rate(&rk3328_pll_clks[GPLL], 752 priv->cru, GPLL); 753 debug("%s gpll=%lu\n", __func__, priv->gpll_hz); 754 } 755 if (!priv->cpll_hz) { 756 priv->cpll_hz = rockchip_pll_get_rate(&rk3328_pll_clks[CPLL], 757 priv->cru, CPLL); 758 debug("%s cpll=%lu\n", __func__, priv->cpll_hz); 759 } 760 #endif 761 762 switch (clk->id) { 763 case PLL_APLL: 764 case PLL_DPLL: 765 case PLL_CPLL: 766 case PLL_GPLL: 767 case PLL_NPLL: 768 rate = rockchip_pll_get_rate(&rk3328_pll_clks[clk->id - 1], 769 priv->cru, clk->id - 1); 770 break; 771 case ARMCLK: 772 rate = rockchip_pll_get_rate(&rk3328_pll_clks[NPLL], 773 priv->cru, NPLL); 774 break; 775 case ACLK_BUS_PRE: 776 case HCLK_BUS_PRE: 777 case PCLK_BUS_PRE: 778 rate = rk3328_bus_get_clk(priv, clk->id); 779 break; 780 case ACLK_PERI_PRE: 781 case HCLK_PERI: 782 case PCLK_PERI: 783 rate = rk3328_peri_get_clk(priv, clk->id); 784 break; 785 case HCLK_SDMMC: 786 case HCLK_EMMC: 787 case SCLK_SDMMC: 788 case SCLK_EMMC: 789 case SCLK_EMMC_SAMPLE: 790 rate = rk3328_mmc_get_clk(priv, clk->id); 791 break; 792 case SCLK_SPI: 793 rate = rk3328_spi_get_clk(priv); 794 break; 795 #ifndef CONFIG_SPL_BUILD 796 case SCLK_I2C0: 797 case SCLK_I2C1: 798 case SCLK_I2C2: 799 case SCLK_I2C3: 800 rate = rk3328_i2c_get_clk(priv, clk->id); 801 break; 802 case SCLK_PWM: 803 rate = rk3328_pwm_get_clk(priv); 804 break; 805 case SCLK_SARADC: 806 rate = rk3328_saradc_get_clk(priv); 807 break; 808 case SCLK_TSADC: 809 rate = rk3328_tsadc_get_clk(priv); 810 break; 811 case ACLK_VOP_PRE: 812 case ACLK_VIO_PRE: 813 case HCLK_VIO_PRE: 814 case ACLK_VOP: 815 case ACLK_VIO: 816 case HCLK_VIO: 817 rate = rk3328_vop_get_clk(priv, clk->id); 818 break; 819 case SCLK_CRYPTO: 820 rate = rk3328_crypto_get_clk(priv, clk->id); 821 break; 822 #endif 823 default: 824 return -ENOENT; 825 } 826 827 return rate; 828 } 829 830 static ulong rk3328_clk_set_rate(struct clk *clk, ulong rate) 831 { 832 struct rk3328_clk_priv *priv = dev_get_priv(clk->dev); 833 ulong ret = 0; 834 835 switch (clk->id) { 836 case PLL_APLL: 837 case PLL_DPLL: 838 case PLL_NPLL: 839 ret = rockchip_pll_set_rate(&rk3328_pll_clks[clk->id - 1], 840 priv->cru, clk->id - 1, rate); 841 break; 842 case PLL_CPLL: 843 ret = rockchip_pll_set_rate(&rk3328_pll_clks[CPLL], 844 priv->cru, CPLL, rate); 845 priv->cpll_hz = rate; 846 break; 847 case PLL_GPLL: 848 ret = rockchip_pll_set_rate(&rk3328_pll_clks[GPLL], 849 priv->cru, GPLL, rate); 850 priv->gpll_hz = rate; 851 break; 852 case ARMCLK: 853 if (priv->armclk_hz) 854 ret = rk3328_armclk_set_clk(priv, rate); 855 priv->armclk_hz = rate; 856 break; 857 case ACLK_BUS_PRE: 858 case HCLK_BUS_PRE: 859 case PCLK_BUS_PRE: 860 rate = rk3328_bus_set_clk(priv, clk->id, rate); 861 break; 862 case ACLK_PERI_PRE: 863 case HCLK_PERI: 864 case PCLK_PERI: 865 rate = rk3328_peri_set_clk(priv, clk->id, rate); 866 break; 867 case HCLK_SDMMC: 868 case HCLK_EMMC: 869 case SCLK_SDMMC: 870 case SCLK_EMMC: 871 ret = rk3328_mmc_set_clk(priv, clk->id, rate); 872 break; 873 case SCLK_SPI: 874 ret = rk3328_spi_set_clk(priv, rate); 875 break; 876 #ifndef CONFIG_SPL_BUILD 877 case SCLK_I2C0: 878 case SCLK_I2C1: 879 case SCLK_I2C2: 880 case SCLK_I2C3: 881 ret = rk3328_i2c_set_clk(priv, clk->id, rate); 882 break; 883 case SCLK_MAC2IO: 884 ret = rk3328_gmac2io_set_clk(priv, rate); 885 break; 886 case SCLK_PWM: 887 ret = rk3328_pwm_set_clk(priv, rate); 888 break; 889 case SCLK_SARADC: 890 ret = rk3328_saradc_set_clk(priv, rate); 891 break; 892 case SCLK_TSADC: 893 ret = rk3328_tsadc_set_clk(priv, rate); 894 break; 895 case DCLK_LCDC: 896 case ACLK_VOP_PRE: 897 case ACLK_VIO_PRE: 898 case HCLK_VIO_PRE: 899 case ACLK_VOP: 900 case ACLK_VIO: 901 case HCLK_VIO: 902 rate = rk3328_vop_set_clk(priv, clk->id, rate); 903 break; 904 case SCLK_CRYPTO: 905 rate = rk3328_crypto_set_clk(priv, clk->id, rate); 906 break; 907 #endif 908 case SCLK_PDM: 909 case SCLK_RTC32K: 910 case SCLK_UART0: 911 case SCLK_UART1: 912 case SCLK_UART2: 913 case SCLK_SDIO: 914 case SCLK_TSP: 915 case SCLK_WIFI: 916 case ACLK_RGA_PRE: 917 case SCLK_RGA: 918 case ACLK_RKVDEC_PRE: 919 case ACLK_RKVENC: 920 case ACLK_VPU_PRE: 921 case SCLK_VDEC_CABAC: 922 case SCLK_VDEC_CORE: 923 case SCLK_VENC_CORE: 924 case SCLK_VENC_DSP: 925 case SCLK_EFUSE: 926 case PCLK_DDR: 927 case ACLK_GMAC: 928 case PCLK_GMAC: 929 case SCLK_USB3OTG_SUSPEND: 930 return 0; 931 default: 932 return -ENOENT; 933 } 934 935 return ret; 936 } 937 938 #ifndef CONFIG_SPL_BUILD 939 static int rk3328_gmac2io_set_parent(struct clk *clk, struct clk *parent) 940 { 941 struct rk3328_grf_regs *grf; 942 const char *clock_output_name; 943 int ret; 944 945 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 946 947 /* 948 * If the requested parent is in the same clock-controller and the id 949 * is SCLK_MAC2IO_SRC ("clk_mac2io_src"), switch to the internal clock. 950 */ 951 if ((parent->dev == clk->dev) && (parent->id == SCLK_MAC2IO_SRC)) { 952 debug("%s: switching RGMII to SCLK_MAC2IO_SRC\n", __func__); 953 rk_clrreg(&grf->mac_con[1], BIT(10)); 954 return 0; 955 } 956 957 /* 958 * Otherwise, we need to check the clock-output-names of the 959 * requested parent to see if the requested id is "gmac_clkin". 960 */ 961 ret = dev_read_string_index(parent->dev, "clock-output-names", 962 parent->id, &clock_output_name); 963 if (ret < 0) 964 return -ENODATA; 965 966 /* If this is "gmac_clkin", switch to the external clock input */ 967 if (!strcmp(clock_output_name, "gmac_clkin")) { 968 debug("%s: switching RGMII to CLKIN\n", __func__); 969 rk_setreg(&grf->mac_con[1], BIT(10)); 970 return 0; 971 } 972 973 return -EINVAL; 974 } 975 976 static int rk3328_gmac2io_ext_set_parent(struct clk *clk, struct clk *parent) 977 { 978 struct rk3328_grf_regs *grf; 979 const char *clock_output_name; 980 int ret; 981 982 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 983 984 /* 985 * If the requested parent is in the same clock-controller and the id 986 * is SCLK_MAC2IO ("clk_mac2io"), switch to the internal clock. 987 */ 988 if ((parent->dev == clk->dev) && (parent->id == SCLK_MAC2IO)) { 989 debug("%s: switching RGMII to SCLK_MAC2IO\n", __func__); 990 rk_clrreg(&grf->soc_con[4], BIT(14)); 991 return 0; 992 } 993 994 /* 995 * Otherwise, we need to check the clock-output-names of the 996 * requested parent to see if the requested id is "gmac_clkin". 997 */ 998 ret = dev_read_string_index(parent->dev, "clock-output-names", 999 parent->id, &clock_output_name); 1000 if (ret < 0) 1001 return -ENODATA; 1002 1003 /* If this is "gmac_clkin", switch to the external clock input */ 1004 if (!strcmp(clock_output_name, "gmac_clkin")) { 1005 debug("%s: switching RGMII to CLKIN\n", __func__); 1006 rk_setreg(&grf->soc_con[4], BIT(14)); 1007 return 0; 1008 } 1009 1010 return -EINVAL; 1011 } 1012 1013 static int rk3328_lcdc_set_parent(struct clk *clk, struct clk *parent) 1014 { 1015 struct rk3328_clk_priv *priv = dev_get_priv(clk->dev); 1016 1017 if (parent->id == HDMIPHY) 1018 rk_clrsetreg(&priv->cru->clksel_con[40], 1019 DCLK_LCDC_SEL_MASK, 1020 DCLK_LCDC_SEL_HDMIPHY << DCLK_LCDC_SEL_SHIFT); 1021 else if (parent->id == PLL_CPLL) 1022 rk_clrsetreg(&priv->cru->clksel_con[40], 1023 DCLK_LCDC_SEL_MASK | DCLK_LCDC_PLL_SEL_MASK, 1024 (DCLK_LCDC_SEL_PLL << DCLK_LCDC_SEL_SHIFT) | 1025 (DCLK_LCDC_PLL_SEL_CPLL << 1026 DCLK_LCDC_PLL_SEL_SHIFT)); 1027 else 1028 rk_clrsetreg(&priv->cru->clksel_con[40], 1029 DCLK_LCDC_SEL_MASK | DCLK_LCDC_PLL_SEL_MASK, 1030 (DCLK_LCDC_SEL_PLL << DCLK_LCDC_SEL_SHIFT) | 1031 (DCLK_LCDC_PLL_SEL_GPLL << 1032 DCLK_LCDC_PLL_SEL_SHIFT)); 1033 1034 return 0; 1035 } 1036 #endif 1037 1038 static int rk3328_clk_set_parent(struct clk *clk, struct clk *parent) 1039 { 1040 switch (clk->id) { 1041 #ifndef CONFIG_SPL_BUILD 1042 case SCLK_MAC2IO: 1043 return rk3328_gmac2io_set_parent(clk, parent); 1044 case SCLK_MAC2IO_EXT: 1045 return rk3328_gmac2io_ext_set_parent(clk, parent); 1046 case DCLK_LCDC: 1047 return rk3328_lcdc_set_parent(clk, parent); 1048 #endif 1049 case SCLK_PDM: 1050 case SCLK_RTC32K: 1051 case SCLK_UART0: 1052 case SCLK_UART1: 1053 case SCLK_UART2: 1054 return 0; 1055 } 1056 1057 debug("%s: unsupported clk %ld\n", __func__, clk->id); 1058 return -ENOENT; 1059 } 1060 1061 #define ROCKCHIP_MMC_DELAY_SEL BIT(10) 1062 #define ROCKCHIP_MMC_DEGREE_MASK 0x3 1063 #define ROCKCHIP_MMC_DELAYNUM_OFFSET 2 1064 #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET) 1065 1066 #define PSECS_PER_SEC 1000000000000LL 1067 /* 1068 * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to 1069 * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg. 1070 */ 1071 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60 1072 1073 int rk3328_mmc_get_phase(struct clk *clk) 1074 { 1075 struct rk3328_clk_priv *priv = dev_get_priv(clk->dev); 1076 struct rk3328_cru *cru = priv->cru; 1077 u32 raw_value, delay_num; 1078 u16 degrees = 0; 1079 ulong rate; 1080 1081 rate = rk3328_clk_get_rate(clk); 1082 1083 if (rate < 0) 1084 return rate; 1085 1086 if (clk->id == SCLK_EMMC_SAMPLE) 1087 raw_value = readl(&cru->emmc_con[1]); 1088 else if (clk->id == SCLK_SDMMC_SAMPLE) 1089 raw_value = readl(&cru->sdmmc_con[1]); 1090 else 1091 raw_value = readl(&cru->sdio_con[1]); 1092 1093 raw_value >>= 1; 1094 degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90; 1095 1096 if (raw_value & ROCKCHIP_MMC_DELAY_SEL) { 1097 /* degrees/delaynum * 10000 */ 1098 unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) * 1099 36 * (rate / 1000000); 1100 1101 delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK); 1102 delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET; 1103 degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000); 1104 } 1105 1106 return degrees % 360; 1107 } 1108 1109 int rk3328_mmc_set_phase(struct clk *clk, u32 degrees) 1110 { 1111 struct rk3328_clk_priv *priv = dev_get_priv(clk->dev); 1112 struct rk3328_cru *cru = priv->cru; 1113 u8 nineties, remainder, delay_num; 1114 u32 raw_value, delay; 1115 ulong rate; 1116 1117 rate = rk3328_clk_get_rate(clk); 1118 1119 if (rate < 0) 1120 return rate; 1121 1122 nineties = degrees / 90; 1123 remainder = (degrees % 90); 1124 1125 /* 1126 * Convert to delay; do a little extra work to make sure we 1127 * don't overflow 32-bit / 64-bit numbers. 1128 */ 1129 delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */ 1130 delay *= remainder; 1131 delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 * 1132 (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10)); 1133 1134 delay_num = (u8)min_t(u32, delay, 255); 1135 1136 raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0; 1137 raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET; 1138 raw_value |= nineties; 1139 1140 raw_value <<= 1; 1141 if (clk->id == SCLK_EMMC_SAMPLE) 1142 writel(raw_value | 0xffff0000, &cru->emmc_con[1]); 1143 else if (clk->id == SCLK_SDMMC_SAMPLE) 1144 writel(raw_value | 0xffff0000, &cru->sdmmc_con[1]); 1145 else 1146 writel(raw_value | 0xffff0000, &cru->sdio_con[1]); 1147 1148 debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n", 1149 degrees, delay_num, raw_value, rk3328_mmc_get_phase(clk)); 1150 1151 return 0; 1152 } 1153 1154 static int rk3328_clk_get_phase(struct clk *clk) 1155 { 1156 int ret; 1157 1158 debug("%s %ld\n", __func__, clk->id); 1159 switch (clk->id) { 1160 case SCLK_EMMC_SAMPLE: 1161 case SCLK_SDMMC_SAMPLE: 1162 case SCLK_SDIO_SAMPLE: 1163 ret = rk3328_mmc_get_phase(clk); 1164 break; 1165 default: 1166 return -ENOENT; 1167 } 1168 1169 return ret; 1170 } 1171 1172 static int rk3328_clk_set_phase(struct clk *clk, int degrees) 1173 { 1174 int ret; 1175 1176 debug("%s %ld\n", __func__, clk->id); 1177 switch (clk->id) { 1178 case SCLK_EMMC_SAMPLE: 1179 case SCLK_SDMMC_SAMPLE: 1180 case SCLK_SDIO_SAMPLE: 1181 ret = rk3328_mmc_set_phase(clk, degrees); 1182 break; 1183 default: 1184 return -ENOENT; 1185 } 1186 1187 return ret; 1188 } 1189 1190 static struct clk_ops rk3328_clk_ops = { 1191 .get_rate = rk3328_clk_get_rate, 1192 .set_rate = rk3328_clk_set_rate, 1193 .set_parent = rk3328_clk_set_parent, 1194 .get_phase = rk3328_clk_get_phase, 1195 .set_phase = rk3328_clk_set_phase, 1196 }; 1197 1198 static void rkclk_init(struct rk3328_clk_priv *priv) 1199 { 1200 if (rockchip_pll_get_rate(&rk3328_pll_clks[NPLL], 1201 priv->cru, NPLL) != APLL_HZ) 1202 rk3328_armclk_set_clk(priv, APLL_HZ); 1203 1204 priv->gpll_hz = rockchip_pll_get_rate(&rk3328_pll_clks[GPLL], 1205 priv->cru, GPLL); 1206 priv->cpll_hz = rockchip_pll_get_rate(&rk3328_pll_clks[CPLL], 1207 priv->cru, CPLL); 1208 1209 /* before set pll set child div first */ 1210 rk_clrsetreg(&priv->cru->clksel_con[24], (0x3f << 8) | (0x3f << 0), 1211 (0x17 << 8) | (0x17 << 0)); 1212 rk_clrsetreg(&priv->cru->clksel_con[27], (0x1f << 8) | (0x1f << 0), 1213 (0x17 << 8) | (0x17 << 0)); 1214 rk_clrsetreg(&priv->cru->clksel_con[31], 0xff << 0, 0xb << 0); 1215 rk_clrsetreg(&priv->cru->clksel_con[43], 0xff << 0, 0xb << 0); 1216 rk_clrsetreg(&priv->cru->clksel_con[52], 0x1f << 8, 0x5 << 8); 1217 1218 rockchip_pll_set_rate(&rk3328_pll_clks[GPLL], 1219 priv->cru, GPLL, GPLL_HZ); 1220 priv->gpll_hz = GPLL_HZ; 1221 1222 rockchip_pll_set_rate(&rk3328_pll_clks[CPLL], 1223 priv->cru, CPLL, CPLL_HZ); 1224 priv->cpll_hz = CPLL_HZ; 1225 1226 rk3328_bus_set_clk(priv, ACLK_BUS_PRE, ACLK_BUS_HZ); 1227 rk3328_bus_set_clk(priv, HCLK_BUS_PRE, ACLK_BUS_HZ / 2); 1228 rk3328_bus_set_clk(priv, PCLK_BUS_PRE, ACLK_BUS_HZ / 2); 1229 rk3328_peri_set_clk(priv, ACLK_PERI_PRE, ACLK_PERI_HZ); 1230 rk3328_peri_set_clk(priv, HCLK_PERI, ACLK_PERI_HZ / 2); 1231 rk3328_peri_set_clk(priv, PCLK_PERI, ACLK_PERI_HZ / 2); 1232 /*rk3328_mmc_set_clk(priv, SCLK_EMMC, rate);*/ 1233 1234 /* set usbphy and hdmiphy from phy */ 1235 rk_clrsetreg(&priv->cru->misc, (0x1 << 13) | 1236 (0x1 << 15), (0 << 15) | (0 << 13)); 1237 } 1238 1239 static int rk3328_clk_probe(struct udevice *dev) 1240 { 1241 struct rk3328_clk_priv *priv = dev_get_priv(dev); 1242 int ret = 0; 1243 1244 priv->sync_kernel = false; 1245 if (!priv->armclk_enter_hz) 1246 priv->armclk_enter_hz = 1247 rockchip_pll_get_rate(&rk3328_pll_clks[NPLL], 1248 priv->cru, NPLL); 1249 rkclk_init(priv); 1250 if (!priv->armclk_init_hz) 1251 priv->armclk_init_hz = 1252 rockchip_pll_get_rate(&rk3328_pll_clks[NPLL], 1253 priv->cru, NPLL); 1254 1255 ret = clk_set_defaults(dev); 1256 if (ret) 1257 debug("%s clk_set_defaults failed %d\n", __func__, ret); 1258 else 1259 priv->sync_kernel = true; 1260 1261 return 0; 1262 } 1263 1264 static int rk3328_clk_ofdata_to_platdata(struct udevice *dev) 1265 { 1266 struct rk3328_clk_priv *priv = dev_get_priv(dev); 1267 1268 priv->cru = dev_read_addr_ptr(dev); 1269 1270 return 0; 1271 } 1272 1273 static int rk3328_clk_bind(struct udevice *dev) 1274 { 1275 int ret; 1276 struct udevice *sys_child, *sf_child; 1277 struct sysreset_reg *priv; 1278 struct softreset_reg *sf_priv; 1279 1280 /* The reset driver does not have a device node, so bind it here */ 1281 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset", 1282 &sys_child); 1283 if (ret) { 1284 debug("Warning: No sysreset driver: ret=%d\n", ret); 1285 } else { 1286 priv = malloc(sizeof(struct sysreset_reg)); 1287 priv->glb_srst_fst_value = offsetof(struct rk3328_cru, 1288 glb_srst_fst_value); 1289 priv->glb_srst_snd_value = offsetof(struct rk3328_cru, 1290 glb_srst_snd_value); 1291 sys_child->priv = priv; 1292 } 1293 1294 ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset", 1295 dev_ofnode(dev), &sf_child); 1296 if (ret) { 1297 debug("Warning: No rockchip reset driver: ret=%d\n", ret); 1298 } else { 1299 sf_priv = malloc(sizeof(struct softreset_reg)); 1300 sf_priv->sf_reset_offset = offsetof(struct rk3328_cru, 1301 softrst_con[0]); 1302 sf_priv->sf_reset_num = 12; 1303 sf_child->priv = sf_priv; 1304 } 1305 1306 return 0; 1307 } 1308 1309 static const struct udevice_id rk3328_clk_ids[] = { 1310 { .compatible = "rockchip,rk3328-cru" }, 1311 { } 1312 }; 1313 1314 U_BOOT_DRIVER(rockchip_rk3328_cru) = { 1315 .name = "rockchip_rk3328_cru", 1316 .id = UCLASS_CLK, 1317 .of_match = rk3328_clk_ids, 1318 .priv_auto_alloc_size = sizeof(struct rk3328_clk_priv), 1319 .ofdata_to_platdata = rk3328_clk_ofdata_to_platdata, 1320 .ops = &rk3328_clk_ops, 1321 .bind = rk3328_clk_bind, 1322 .probe = rk3328_clk_probe, 1323 }; 1324 1325 #ifndef CONFIG_SPL_BUILD 1326 /** 1327 * soc_clk_dump() - Print clock frequencies 1328 * Returns zero on success 1329 * 1330 * Implementation for the clk dump command. 1331 */ 1332 int soc_clk_dump(void) 1333 { 1334 struct udevice *cru_dev; 1335 struct rk3328_clk_priv *priv; 1336 const struct rk3328_clk_info *clk_dump; 1337 struct clk clk; 1338 unsigned long clk_count = ARRAY_SIZE(clks_dump); 1339 unsigned long rate; 1340 int i, ret; 1341 1342 ret = uclass_get_device_by_driver(UCLASS_CLK, 1343 DM_GET_DRIVER(rockchip_rk3328_cru), 1344 &cru_dev); 1345 if (ret) { 1346 printf("%s failed to get cru device\n", __func__); 1347 return ret; 1348 } 1349 1350 priv = dev_get_priv(cru_dev); 1351 printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n", 1352 priv->sync_kernel ? "sync kernel" : "uboot", 1353 priv->armclk_enter_hz / 1000, 1354 priv->armclk_init_hz / 1000, 1355 priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0, 1356 priv->set_armclk_rate ? " KHz" : "N/A"); 1357 for (i = 0; i < clk_count; i++) { 1358 clk_dump = &clks_dump[i]; 1359 if (clk_dump->name) { 1360 clk.id = clk_dump->id; 1361 if (clk_dump->is_cru) 1362 ret = clk_request(cru_dev, &clk); 1363 if (ret < 0) 1364 return ret; 1365 1366 rate = clk_get_rate(&clk); 1367 clk_free(&clk); 1368 if (i == 0) { 1369 if (rate < 0) 1370 printf(" %s %s\n", clk_dump->name, 1371 "unknown"); 1372 else 1373 printf(" %s %lu KHz\n", clk_dump->name, 1374 rate / 1000); 1375 } else { 1376 if (rate < 0) 1377 printf(" %s %s\n", clk_dump->name, 1378 "unknown"); 1379 else 1380 printf(" %s %lu KHz\n", clk_dump->name, 1381 rate / 1000); 1382 } 1383 } 1384 } 1385 1386 return 0; 1387 } 1388 #endif 1389