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