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 struct pll_div { 24 u32 refdiv; 25 u32 fbdiv; 26 u32 postdiv1; 27 u32 postdiv2; 28 u32 frac; 29 }; 30 31 #define RATE_TO_DIV(input_rate, output_rate) \ 32 ((input_rate) / (output_rate) - 1); 33 #define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1)) 34 35 #define PLL_DIVISORS(hz, _refdiv, _postdiv1, _postdiv2) {\ 36 .refdiv = _refdiv,\ 37 .fbdiv = (u32)((u64)hz * _refdiv * _postdiv1 * _postdiv2 / OSC_HZ),\ 38 .postdiv1 = _postdiv1, .postdiv2 = _postdiv2}; 39 40 static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 1, 4, 1); 41 static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 2, 2, 1); 42 43 static const struct pll_div apll_816_cfg = PLL_DIVISORS(816 * MHz, 1, 2, 1); 44 static const struct pll_div apll_600_cfg = PLL_DIVISORS(600 * MHz, 1, 3, 1); 45 46 static const struct pll_div *apll_cfgs[] = { 47 [APLL_816_MHZ] = &apll_816_cfg, 48 [APLL_600_MHZ] = &apll_600_cfg, 49 }; 50 51 enum { 52 /* PLL_CON0 */ 53 PLL_POSTDIV1_SHIFT = 12, 54 PLL_POSTDIV1_MASK = 0x7 << PLL_POSTDIV1_SHIFT, 55 PLL_FBDIV_SHIFT = 0, 56 PLL_FBDIV_MASK = 0xfff, 57 58 /* PLL_CON1 */ 59 PLL_DSMPD_SHIFT = 12, 60 PLL_DSMPD_MASK = 1 << PLL_DSMPD_SHIFT, 61 PLL_INTEGER_MODE = 1, 62 PLL_LOCK_STATUS_SHIFT = 10, 63 PLL_LOCK_STATUS_MASK = 1 << PLL_LOCK_STATUS_SHIFT, 64 PLL_POSTDIV2_SHIFT = 6, 65 PLL_POSTDIV2_MASK = 0x7 << PLL_POSTDIV2_SHIFT, 66 PLL_REFDIV_SHIFT = 0, 67 PLL_REFDIV_MASK = 0x3f, 68 69 /* PLL_CON2 */ 70 PLL_FRACDIV_SHIFT = 0, 71 PLL_FRACDIV_MASK = 0xffffff, 72 73 /* MODE_CON */ 74 APLL_MODE_SHIFT = 0, 75 NPLL_MODE_SHIFT = 1, 76 DPLL_MODE_SHIFT = 4, 77 CPLL_MODE_SHIFT = 8, 78 GPLL_MODE_SHIFT = 12, 79 PLL_MODE_SLOW = 0, 80 PLL_MODE_NORM, 81 82 /* CLKSEL_CON0 */ 83 CLK_CORE_PLL_SEL_APLL = 0, 84 CLK_CORE_PLL_SEL_GPLL, 85 CLK_CORE_PLL_SEL_DPLL, 86 CLK_CORE_PLL_SEL_NPLL, 87 CLK_CORE_PLL_SEL_SHIFT = 6, 88 CLK_CORE_PLL_SEL_MASK = 3 << CLK_CORE_PLL_SEL_SHIFT, 89 CLK_CORE_DIV_SHIFT = 0, 90 CLK_CORE_DIV_MASK = 0x1f, 91 92 /* CLKSEL_CON1 */ 93 ACLKM_CORE_DIV_SHIFT = 4, 94 ACLKM_CORE_DIV_MASK = 0x7 << ACLKM_CORE_DIV_SHIFT, 95 PCLK_DBG_DIV_SHIFT = 0, 96 PCLK_DBG_DIV_MASK = 0xF << PCLK_DBG_DIV_SHIFT, 97 98 /* CLKSEL_CON27 */ 99 GMAC2IO_PLL_SEL_SHIFT = 7, 100 GMAC2IO_PLL_SEL_MASK = 1 << GMAC2IO_PLL_SEL_SHIFT, 101 GMAC2IO_PLL_SEL_CPLL = 0, 102 GMAC2IO_PLL_SEL_GPLL = 1, 103 GMAC2IO_CLK_DIV_MASK = 0x1f, 104 GMAC2IO_CLK_DIV_SHIFT = 0, 105 106 /* CLKSEL_CON28 */ 107 ACLK_PERIHP_PLL_SEL_CPLL = 0, 108 ACLK_PERIHP_PLL_SEL_GPLL, 109 ACLK_PERIHP_PLL_SEL_HDMIPHY, 110 ACLK_PERIHP_PLL_SEL_SHIFT = 6, 111 ACLK_PERIHP_PLL_SEL_MASK = 3 << ACLK_PERIHP_PLL_SEL_SHIFT, 112 ACLK_PERIHP_DIV_CON_SHIFT = 0, 113 ACLK_PERIHP_DIV_CON_MASK = 0x1f, 114 115 /* CLKSEL_CON29 */ 116 PCLK_PERIHP_DIV_CON_SHIFT = 4, 117 PCLK_PERIHP_DIV_CON_MASK = 0x7 << PCLK_PERIHP_DIV_CON_SHIFT, 118 HCLK_PERIHP_DIV_CON_SHIFT = 0, 119 HCLK_PERIHP_DIV_CON_MASK = 3 << HCLK_PERIHP_DIV_CON_SHIFT, 120 121 /* CLKSEL_CON22 */ 122 CLK_TSADC_DIV_CON_SHIFT = 0, 123 CLK_TSADC_DIV_CON_MASK = 0x3ff, 124 125 /* CLKSEL_CON23 */ 126 CLK_SARADC_DIV_CON_SHIFT = 0, 127 CLK_SARADC_DIV_CON_MASK = GENMASK(9, 0), 128 CLK_SARADC_DIV_CON_WIDTH = 10, 129 130 /* CLKSEL_CON24 */ 131 CLK_PWM_PLL_SEL_CPLL = 0, 132 CLK_PWM_PLL_SEL_GPLL, 133 CLK_PWM_PLL_SEL_SHIFT = 15, 134 CLK_PWM_PLL_SEL_MASK = 1 << CLK_PWM_PLL_SEL_SHIFT, 135 CLK_PWM_DIV_CON_SHIFT = 8, 136 CLK_PWM_DIV_CON_MASK = 0x7f << CLK_PWM_DIV_CON_SHIFT, 137 138 CLK_SPI_PLL_SEL_CPLL = 0, 139 CLK_SPI_PLL_SEL_GPLL, 140 CLK_SPI_PLL_SEL_SHIFT = 7, 141 CLK_SPI_PLL_SEL_MASK = 1 << CLK_SPI_PLL_SEL_SHIFT, 142 CLK_SPI_DIV_CON_SHIFT = 0, 143 CLK_SPI_DIV_CON_MASK = 0x7f << CLK_SPI_DIV_CON_SHIFT, 144 145 /* CLKSEL_CON30 */ 146 CLK_SDMMC_PLL_SEL_CPLL = 0, 147 CLK_SDMMC_PLL_SEL_GPLL, 148 CLK_SDMMC_PLL_SEL_24M, 149 CLK_SDMMC_PLL_SEL_USBPHY, 150 CLK_SDMMC_PLL_SHIFT = 8, 151 CLK_SDMMC_PLL_MASK = 0x3 << CLK_SDMMC_PLL_SHIFT, 152 CLK_SDMMC_DIV_CON_SHIFT = 0, 153 CLK_SDMMC_DIV_CON_MASK = 0xff << CLK_SDMMC_DIV_CON_SHIFT, 154 155 /* CLKSEL_CON32 */ 156 CLK_EMMC_PLL_SEL_CPLL = 0, 157 CLK_EMMC_PLL_SEL_GPLL, 158 CLK_EMMC_PLL_SEL_24M, 159 CLK_EMMC_PLL_SEL_USBPHY, 160 CLK_EMMC_PLL_SHIFT = 8, 161 CLK_EMMC_PLL_MASK = 0x3 << CLK_EMMC_PLL_SHIFT, 162 CLK_EMMC_DIV_CON_SHIFT = 0, 163 CLK_EMMC_DIV_CON_MASK = 0xff << CLK_EMMC_DIV_CON_SHIFT, 164 165 /* CLKSEL_CON34 */ 166 CLK_I2C_PLL_SEL_CPLL = 0, 167 CLK_I2C_PLL_SEL_GPLL, 168 CLK_I2C_DIV_CON_MASK = 0x7f, 169 CLK_I2C_PLL_SEL_MASK = 1, 170 CLK_I2C1_PLL_SEL_SHIFT = 15, 171 CLK_I2C1_DIV_CON_SHIFT = 8, 172 CLK_I2C0_PLL_SEL_SHIFT = 7, 173 CLK_I2C0_DIV_CON_SHIFT = 0, 174 175 /* CLKSEL_CON35 */ 176 CLK_I2C3_PLL_SEL_SHIFT = 15, 177 CLK_I2C3_DIV_CON_SHIFT = 8, 178 CLK_I2C2_PLL_SEL_SHIFT = 7, 179 CLK_I2C2_DIV_CON_SHIFT = 0, 180 }; 181 182 #define VCO_MAX_KHZ (3200 * (MHz / KHz)) 183 #define VCO_MIN_KHZ (800 * (MHz / KHz)) 184 #define OUTPUT_MAX_KHZ (3200 * (MHz / KHz)) 185 #define OUTPUT_MIN_KHZ (16 * (MHz / KHz)) 186 187 /* 188 * the div restructions of pll in integer mode, these are defined in 189 * * CRU_*PLL_CON0 or PMUCRU_*PLL_CON0 190 */ 191 #define PLL_DIV_MIN 16 192 #define PLL_DIV_MAX 3200 193 194 /* 195 * How to calculate the PLL(from TRM V0.3 Part 1 Page 63): 196 * Formulas also embedded within the Fractional PLL Verilog model: 197 * If DSMPD = 1 (DSM is disabled, "integer mode") 198 * FOUTVCO = FREF / REFDIV * FBDIV 199 * FOUTPOSTDIV = FOUTVCO / POSTDIV1 / POSTDIV2 200 * Where: 201 * FOUTVCO = Fractional PLL non-divided output frequency 202 * FOUTPOSTDIV = Fractional PLL divided output frequency 203 * (output of second post divider) 204 * FREF = Fractional PLL input reference frequency, (the OSC_HZ 24MHz input) 205 * REFDIV = Fractional PLL input reference clock divider 206 * FBDIV = Integer value programmed into feedback divide 207 * 208 */ 209 static void rkclk_set_pll(struct rk3328_cru *cru, enum rk_clk_id clk_id, 210 const struct pll_div *div) 211 { 212 u32 *pll_con; 213 u32 mode_shift, mode_mask; 214 215 pll_con = NULL; 216 mode_shift = 0; 217 switch (clk_id) { 218 case CLK_ARM: 219 pll_con = cru->apll_con; 220 mode_shift = APLL_MODE_SHIFT; 221 break; 222 case CLK_DDR: 223 pll_con = cru->dpll_con; 224 mode_shift = DPLL_MODE_SHIFT; 225 break; 226 case CLK_CODEC: 227 pll_con = cru->cpll_con; 228 mode_shift = CPLL_MODE_SHIFT; 229 break; 230 case CLK_GENERAL: 231 pll_con = cru->gpll_con; 232 mode_shift = GPLL_MODE_SHIFT; 233 break; 234 case CLK_NEW: 235 pll_con = cru->npll_con; 236 mode_shift = NPLL_MODE_SHIFT; 237 break; 238 default: 239 break; 240 } 241 mode_mask = 1 << mode_shift; 242 243 /* All 8 PLLs have same VCO and output frequency range restrictions. */ 244 u32 vco_khz = OSC_HZ / 1000 * div->fbdiv / div->refdiv; 245 u32 output_khz = vco_khz / div->postdiv1 / div->postdiv2; 246 247 debug("PLL at %p: fbdiv=%d, refdiv=%d, postdiv1=%d, \ 248 postdiv2=%d, vco=%u khz, output=%u khz\n", 249 pll_con, div->fbdiv, div->refdiv, div->postdiv1, 250 div->postdiv2, vco_khz, output_khz); 251 assert(vco_khz >= VCO_MIN_KHZ && vco_khz <= VCO_MAX_KHZ && 252 output_khz >= OUTPUT_MIN_KHZ && output_khz <= OUTPUT_MAX_KHZ && 253 div->fbdiv >= PLL_DIV_MIN && div->fbdiv <= PLL_DIV_MAX); 254 255 /* 256 * When power on or changing PLL setting, 257 * we must force PLL into slow mode to ensure output stable clock. 258 */ 259 rk_clrsetreg(&cru->mode_con, mode_mask, PLL_MODE_SLOW << mode_shift); 260 261 /* use integer mode */ 262 rk_clrsetreg(&pll_con[1], PLL_DSMPD_MASK, 263 PLL_INTEGER_MODE << PLL_DSMPD_SHIFT); 264 265 rk_clrsetreg(&pll_con[0], 266 PLL_FBDIV_MASK | PLL_POSTDIV1_MASK, 267 (div->fbdiv << PLL_FBDIV_SHIFT) | 268 (div->postdiv1 << PLL_POSTDIV1_SHIFT)); 269 rk_clrsetreg(&pll_con[1], 270 PLL_POSTDIV2_MASK | PLL_REFDIV_MASK, 271 (div->postdiv2 << PLL_POSTDIV2_SHIFT) | 272 (div->refdiv << PLL_REFDIV_SHIFT)); 273 274 /* waiting for pll lock */ 275 while (!(readl(&pll_con[1]) & (1 << PLL_LOCK_STATUS_SHIFT))) 276 udelay(1); 277 278 /* pll enter normal mode */ 279 rk_clrsetreg(&cru->mode_con, mode_mask, PLL_MODE_NORM << mode_shift); 280 } 281 282 static void rkclk_init(struct rk3328_cru *cru) 283 { 284 u32 aclk_div; 285 u32 hclk_div; 286 u32 pclk_div; 287 288 /* configure gpll cpll */ 289 rkclk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg); 290 rkclk_set_pll(cru, CLK_CODEC, &cpll_init_cfg); 291 292 /* configure perihp aclk, hclk, pclk */ 293 aclk_div = GPLL_HZ / PERIHP_ACLK_HZ - 1; 294 hclk_div = PERIHP_ACLK_HZ / PERIHP_HCLK_HZ - 1; 295 pclk_div = PERIHP_ACLK_HZ / PERIHP_PCLK_HZ - 1; 296 297 rk_clrsetreg(&cru->clksel_con[28], 298 ACLK_PERIHP_PLL_SEL_MASK | ACLK_PERIHP_DIV_CON_MASK, 299 ACLK_PERIHP_PLL_SEL_GPLL << ACLK_PERIHP_PLL_SEL_SHIFT | 300 aclk_div << ACLK_PERIHP_DIV_CON_SHIFT); 301 rk_clrsetreg(&cru->clksel_con[29], 302 PCLK_PERIHP_DIV_CON_MASK | HCLK_PERIHP_DIV_CON_MASK, 303 pclk_div << PCLK_PERIHP_DIV_CON_SHIFT | 304 hclk_div << HCLK_PERIHP_DIV_CON_SHIFT); 305 } 306 307 void rk3328_configure_cpu(struct rk3328_cru *cru, 308 enum apll_frequencies apll_freq) 309 { 310 u32 clk_core_div; 311 u32 aclkm_div; 312 u32 pclk_dbg_div; 313 314 rkclk_set_pll(cru, CLK_ARM, apll_cfgs[apll_freq]); 315 316 clk_core_div = APLL_HZ / CLK_CORE_HZ - 1; 317 aclkm_div = APLL_HZ / ACLKM_CORE_HZ / (clk_core_div + 1) - 1; 318 pclk_dbg_div = APLL_HZ / PCLK_DBG_HZ / (clk_core_div + 1) - 1; 319 320 rk_clrsetreg(&cru->clksel_con[0], 321 CLK_CORE_PLL_SEL_MASK | CLK_CORE_DIV_MASK, 322 CLK_CORE_PLL_SEL_APLL << CLK_CORE_PLL_SEL_SHIFT | 323 clk_core_div << CLK_CORE_DIV_SHIFT); 324 325 rk_clrsetreg(&cru->clksel_con[1], 326 PCLK_DBG_DIV_MASK | ACLKM_CORE_DIV_MASK, 327 pclk_dbg_div << PCLK_DBG_DIV_SHIFT | 328 aclkm_div << ACLKM_CORE_DIV_SHIFT); 329 } 330 331 332 static ulong rk3328_i2c_get_clk(struct rk3328_cru *cru, ulong clk_id) 333 { 334 u32 div, con; 335 336 switch (clk_id) { 337 case SCLK_I2C0: 338 con = readl(&cru->clksel_con[34]); 339 div = con >> CLK_I2C0_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK; 340 break; 341 case SCLK_I2C1: 342 con = readl(&cru->clksel_con[34]); 343 div = con >> CLK_I2C1_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK; 344 break; 345 case SCLK_I2C2: 346 con = readl(&cru->clksel_con[35]); 347 div = con >> CLK_I2C2_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK; 348 break; 349 case SCLK_I2C3: 350 con = readl(&cru->clksel_con[35]); 351 div = con >> CLK_I2C3_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK; 352 break; 353 default: 354 printf("do not support this i2c bus\n"); 355 return -EINVAL; 356 } 357 358 return DIV_TO_RATE(GPLL_HZ, div); 359 } 360 361 static ulong rk3328_i2c_set_clk(struct rk3328_cru *cru, ulong clk_id, uint hz) 362 { 363 int src_clk_div; 364 365 src_clk_div = GPLL_HZ / hz; 366 assert(src_clk_div - 1 < 127); 367 368 switch (clk_id) { 369 case SCLK_I2C0: 370 rk_clrsetreg(&cru->clksel_con[34], 371 CLK_I2C_DIV_CON_MASK << CLK_I2C0_DIV_CON_SHIFT | 372 CLK_I2C_PLL_SEL_MASK << CLK_I2C0_PLL_SEL_SHIFT, 373 (src_clk_div - 1) << CLK_I2C0_DIV_CON_SHIFT | 374 CLK_I2C_PLL_SEL_GPLL << CLK_I2C0_PLL_SEL_SHIFT); 375 break; 376 case SCLK_I2C1: 377 rk_clrsetreg(&cru->clksel_con[34], 378 CLK_I2C_DIV_CON_MASK << CLK_I2C1_DIV_CON_SHIFT | 379 CLK_I2C_PLL_SEL_MASK << CLK_I2C1_PLL_SEL_SHIFT, 380 (src_clk_div - 1) << CLK_I2C1_DIV_CON_SHIFT | 381 CLK_I2C_PLL_SEL_GPLL << CLK_I2C1_PLL_SEL_SHIFT); 382 break; 383 case SCLK_I2C2: 384 rk_clrsetreg(&cru->clksel_con[35], 385 CLK_I2C_DIV_CON_MASK << CLK_I2C2_DIV_CON_SHIFT | 386 CLK_I2C_PLL_SEL_MASK << CLK_I2C2_PLL_SEL_SHIFT, 387 (src_clk_div - 1) << CLK_I2C2_DIV_CON_SHIFT | 388 CLK_I2C_PLL_SEL_GPLL << CLK_I2C2_PLL_SEL_SHIFT); 389 break; 390 case SCLK_I2C3: 391 rk_clrsetreg(&cru->clksel_con[35], 392 CLK_I2C_DIV_CON_MASK << CLK_I2C3_DIV_CON_SHIFT | 393 CLK_I2C_PLL_SEL_MASK << CLK_I2C3_PLL_SEL_SHIFT, 394 (src_clk_div - 1) << CLK_I2C3_DIV_CON_SHIFT | 395 CLK_I2C_PLL_SEL_GPLL << CLK_I2C3_PLL_SEL_SHIFT); 396 break; 397 default: 398 printf("do not support this i2c bus\n"); 399 return -EINVAL; 400 } 401 402 return DIV_TO_RATE(GPLL_HZ, src_clk_div); 403 } 404 405 static ulong rk3328_gmac2io_set_clk(struct rk3328_cru *cru, ulong rate) 406 { 407 struct rk3328_grf_regs *grf; 408 ulong ret; 409 410 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 411 412 /* 413 * The RGMII CLK can be derived either from an external "clkin" 414 * or can be generated from internally by a divider from SCLK_MAC. 415 */ 416 if (readl(&grf->mac_con[1]) & BIT(10) && 417 readl(&grf->soc_con[4]) & BIT(14)) { 418 /* An external clock will always generate the right rate... */ 419 ret = rate; 420 } else { 421 u32 con = readl(&cru->clksel_con[27]); 422 ulong pll_rate; 423 u8 div; 424 425 if ((con >> GMAC2IO_PLL_SEL_SHIFT) & GMAC2IO_PLL_SEL_GPLL) 426 pll_rate = GPLL_HZ; 427 else 428 pll_rate = CPLL_HZ; 429 430 div = DIV_ROUND_UP(pll_rate, rate) - 1; 431 if (div <= 0x1f) 432 rk_clrsetreg(&cru->clksel_con[27], GMAC2IO_CLK_DIV_MASK, 433 div << GMAC2IO_CLK_DIV_SHIFT); 434 else 435 debug("Unsupported div for gmac:%d\n", div); 436 437 return DIV_TO_RATE(pll_rate, div); 438 } 439 440 return ret; 441 } 442 443 static ulong rk3328_mmc_get_clk(struct rk3328_cru *cru, uint clk_id) 444 { 445 u32 div, con, con_id; 446 447 switch (clk_id) { 448 case HCLK_SDMMC: 449 case SCLK_SDMMC: 450 con_id = 30; 451 break; 452 case HCLK_EMMC: 453 case SCLK_EMMC: 454 con_id = 32; 455 break; 456 default: 457 return -EINVAL; 458 } 459 con = readl(&cru->clksel_con[con_id]); 460 div = (con & CLK_EMMC_DIV_CON_MASK) >> CLK_EMMC_DIV_CON_SHIFT; 461 462 if ((con & CLK_EMMC_PLL_MASK) >> CLK_EMMC_PLL_SHIFT 463 == CLK_EMMC_PLL_SEL_24M) 464 return DIV_TO_RATE(OSC_HZ, div) / 2; 465 else 466 return DIV_TO_RATE(GPLL_HZ, div) / 2; 467 } 468 469 static ulong rk3328_mmc_set_clk(struct rk3328_cru *cru, 470 ulong clk_id, ulong set_rate) 471 { 472 int src_clk_div; 473 u32 con_id; 474 475 switch (clk_id) { 476 case HCLK_SDMMC: 477 case SCLK_SDMMC: 478 con_id = 30; 479 break; 480 case HCLK_EMMC: 481 case SCLK_EMMC: 482 con_id = 32; 483 break; 484 default: 485 return -EINVAL; 486 } 487 /* Select clk_sdmmc/emmc source from GPLL by default */ 488 /* mmc clock defaulg div 2 internal, need provide double in cru */ 489 src_clk_div = DIV_ROUND_UP(GPLL_HZ / 2, set_rate); 490 491 if (src_clk_div > 127) { 492 /* use 24MHz source for 400KHz clock */ 493 src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, set_rate); 494 rk_clrsetreg(&cru->clksel_con[con_id], 495 CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK, 496 CLK_EMMC_PLL_SEL_24M << CLK_EMMC_PLL_SHIFT | 497 (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT); 498 } else { 499 rk_clrsetreg(&cru->clksel_con[con_id], 500 CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK, 501 CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT | 502 (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT); 503 } 504 505 return rk3328_mmc_get_clk(cru, clk_id); 506 } 507 508 static ulong rk3328_pwm_get_clk(struct rk3328_cru *cru) 509 { 510 u32 div, con; 511 512 con = readl(&cru->clksel_con[24]); 513 div = (con & CLK_PWM_DIV_CON_MASK) >> CLK_PWM_DIV_CON_SHIFT; 514 515 return DIV_TO_RATE(GPLL_HZ, div); 516 } 517 518 static ulong rk3328_pwm_set_clk(struct rk3328_cru *cru, uint hz) 519 { 520 u32 div = GPLL_HZ / hz; 521 522 rk_clrsetreg(&cru->clksel_con[24], 523 CLK_PWM_PLL_SEL_MASK | CLK_PWM_DIV_CON_MASK, 524 CLK_PWM_PLL_SEL_GPLL << CLK_PWM_PLL_SEL_SHIFT | 525 (div - 1) << CLK_PWM_DIV_CON_SHIFT); 526 527 return DIV_TO_RATE(GPLL_HZ, div); 528 } 529 530 static ulong rk3328_saradc_get_clk(struct rk3328_cru *cru) 531 { 532 u32 div, val; 533 534 val = readl(&cru->clksel_con[23]); 535 div = bitfield_extract(val, CLK_SARADC_DIV_CON_SHIFT, 536 CLK_SARADC_DIV_CON_WIDTH); 537 538 return DIV_TO_RATE(OSC_HZ, div); 539 } 540 541 static ulong rk3328_saradc_set_clk(struct rk3328_cru *cru, uint hz) 542 { 543 int src_clk_div; 544 545 src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1; 546 assert(src_clk_div < 128); 547 548 rk_clrsetreg(&cru->clksel_con[23], 549 CLK_SARADC_DIV_CON_MASK, 550 src_clk_div << CLK_SARADC_DIV_CON_SHIFT); 551 552 return rk3328_saradc_get_clk(cru); 553 } 554 555 static ulong rk3328_clk_get_rate(struct clk *clk) 556 { 557 struct rk3328_clk_priv *priv = dev_get_priv(clk->dev); 558 ulong rate = 0; 559 560 switch (clk->id) { 561 case 0 ... 29: 562 return 0; 563 case HCLK_SDMMC: 564 case HCLK_EMMC: 565 case SCLK_SDMMC: 566 case SCLK_EMMC: 567 rate = rk3328_mmc_get_clk(priv->cru, clk->id); 568 break; 569 case SCLK_I2C0: 570 case SCLK_I2C1: 571 case SCLK_I2C2: 572 case SCLK_I2C3: 573 rate = rk3328_i2c_get_clk(priv->cru, clk->id); 574 break; 575 case SCLK_PWM: 576 rate = rk3328_pwm_get_clk(priv->cru); 577 break; 578 case SCLK_SARADC: 579 rate = rk3328_saradc_get_clk(priv->cru); 580 break; 581 default: 582 return -ENOENT; 583 } 584 585 return rate; 586 } 587 588 static ulong rk3328_clk_set_rate(struct clk *clk, ulong rate) 589 { 590 struct rk3328_clk_priv *priv = dev_get_priv(clk->dev); 591 ulong ret = 0; 592 593 switch (clk->id) { 594 case 0 ... 29: 595 return 0; 596 case HCLK_SDMMC: 597 case HCLK_EMMC: 598 case SCLK_SDMMC: 599 case SCLK_EMMC: 600 ret = rk3328_mmc_set_clk(priv->cru, clk->id, rate); 601 break; 602 case SCLK_I2C0: 603 case SCLK_I2C1: 604 case SCLK_I2C2: 605 case SCLK_I2C3: 606 ret = rk3328_i2c_set_clk(priv->cru, clk->id, rate); 607 break; 608 case SCLK_MAC2IO: 609 ret = rk3328_gmac2io_set_clk(priv->cru, rate); 610 break; 611 case SCLK_PWM: 612 ret = rk3328_pwm_set_clk(priv->cru, rate); 613 break; 614 case SCLK_SARADC: 615 ret = rk3328_saradc_set_clk(priv->cru, rate); 616 break; 617 case DCLK_LCDC: 618 case SCLK_PDM: 619 case SCLK_RTC32K: 620 case SCLK_UART0: 621 case SCLK_UART1: 622 case SCLK_UART2: 623 case SCLK_SDIO: 624 case SCLK_TSP: 625 case SCLK_WIFI: 626 case ACLK_BUS_PRE: 627 case HCLK_BUS_PRE: 628 case PCLK_BUS_PRE: 629 case ACLK_PERI_PRE: 630 case HCLK_PERI: 631 case PCLK_PERI: 632 case ACLK_VIO_PRE: 633 case HCLK_VIO_PRE: 634 case ACLK_RGA_PRE: 635 case SCLK_RGA: 636 case ACLK_VOP_PRE: 637 case ACLK_RKVDEC_PRE: 638 case ACLK_RKVENC: 639 case ACLK_VPU_PRE: 640 case SCLK_VDEC_CABAC: 641 case SCLK_VDEC_CORE: 642 case SCLK_VENC_CORE: 643 case SCLK_VENC_DSP: 644 case SCLK_EFUSE: 645 case PCLK_DDR: 646 case ACLK_GMAC: 647 case PCLK_GMAC: 648 case SCLK_USB3OTG_SUSPEND: 649 return 0; 650 default: 651 return -ENOENT; 652 } 653 654 return ret; 655 } 656 657 static int rk3328_gmac2io_set_parent(struct clk *clk, struct clk *parent) 658 { 659 struct rk3328_grf_regs *grf; 660 const char *clock_output_name; 661 int ret; 662 663 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 664 665 /* 666 * If the requested parent is in the same clock-controller and the id 667 * is SCLK_MAC2IO_SRC ("clk_mac2io_src"), switch to the internal clock. 668 */ 669 if ((parent->dev == clk->dev) && (parent->id == SCLK_MAC2IO_SRC)) { 670 debug("%s: switching RGMII to SCLK_MAC2IO_SRC\n", __func__); 671 rk_clrreg(&grf->mac_con[1], BIT(10)); 672 return 0; 673 } 674 675 /* 676 * Otherwise, we need to check the clock-output-names of the 677 * requested parent to see if the requested id is "gmac_clkin". 678 */ 679 ret = dev_read_string_index(parent->dev, "clock-output-names", 680 parent->id, &clock_output_name); 681 if (ret < 0) 682 return -ENODATA; 683 684 /* If this is "gmac_clkin", switch to the external clock input */ 685 if (!strcmp(clock_output_name, "gmac_clkin")) { 686 debug("%s: switching RGMII to CLKIN\n", __func__); 687 rk_setreg(&grf->mac_con[1], BIT(10)); 688 return 0; 689 } 690 691 return -EINVAL; 692 } 693 694 static int rk3328_gmac2io_ext_set_parent(struct clk *clk, struct clk *parent) 695 { 696 struct rk3328_grf_regs *grf; 697 const char *clock_output_name; 698 int ret; 699 700 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 701 702 /* 703 * If the requested parent is in the same clock-controller and the id 704 * is SCLK_MAC2IO ("clk_mac2io"), switch to the internal clock. 705 */ 706 if ((parent->dev == clk->dev) && (parent->id == SCLK_MAC2IO)) { 707 debug("%s: switching RGMII to SCLK_MAC2IO\n", __func__); 708 rk_clrreg(&grf->soc_con[4], BIT(14)); 709 return 0; 710 } 711 712 /* 713 * Otherwise, we need to check the clock-output-names of the 714 * requested parent to see if the requested id is "gmac_clkin". 715 */ 716 ret = dev_read_string_index(parent->dev, "clock-output-names", 717 parent->id, &clock_output_name); 718 if (ret < 0) 719 return -ENODATA; 720 721 /* If this is "gmac_clkin", switch to the external clock input */ 722 if (!strcmp(clock_output_name, "gmac_clkin")) { 723 debug("%s: switching RGMII to CLKIN\n", __func__); 724 rk_setreg(&grf->soc_con[4], BIT(14)); 725 return 0; 726 } 727 728 return -EINVAL; 729 } 730 731 static int rk3328_clk_set_parent(struct clk *clk, struct clk *parent) 732 { 733 switch (clk->id) { 734 case SCLK_MAC2IO: 735 return rk3328_gmac2io_set_parent(clk, parent); 736 case SCLK_MAC2IO_EXT: 737 return rk3328_gmac2io_ext_set_parent(clk, parent); 738 case DCLK_LCDC: 739 case SCLK_PDM: 740 case SCLK_RTC32K: 741 case SCLK_UART0: 742 case SCLK_UART1: 743 case SCLK_UART2: 744 return 0; 745 } 746 747 debug("%s: unsupported clk %ld\n", __func__, clk->id); 748 return -ENOENT; 749 } 750 751 static struct clk_ops rk3328_clk_ops = { 752 .get_rate = rk3328_clk_get_rate, 753 .set_rate = rk3328_clk_set_rate, 754 .set_parent = rk3328_clk_set_parent, 755 }; 756 757 static int rk3328_clk_probe(struct udevice *dev) 758 { 759 struct rk3328_clk_priv *priv = dev_get_priv(dev); 760 761 rkclk_init(priv->cru); 762 763 return 0; 764 } 765 766 static int rk3328_clk_ofdata_to_platdata(struct udevice *dev) 767 { 768 struct rk3328_clk_priv *priv = dev_get_priv(dev); 769 770 priv->cru = dev_read_addr_ptr(dev); 771 772 return 0; 773 } 774 775 static int rk3328_clk_bind(struct udevice *dev) 776 { 777 int ret; 778 struct udevice *sys_child; 779 struct sysreset_reg *priv; 780 781 /* The reset driver does not have a device node, so bind it here */ 782 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset", 783 &sys_child); 784 if (ret) { 785 debug("Warning: No sysreset driver: ret=%d\n", ret); 786 } else { 787 priv = malloc(sizeof(struct sysreset_reg)); 788 priv->glb_srst_fst_value = offsetof(struct rk3328_cru, 789 glb_srst_fst_value); 790 priv->glb_srst_snd_value = offsetof(struct rk3328_cru, 791 glb_srst_snd_value); 792 sys_child->priv = priv; 793 } 794 795 #if CONFIG_IS_ENABLED(CONFIG_RESET_ROCKCHIP) 796 ret = offsetof(struct rk3328_cru, softrst_con[0]); 797 ret = rockchip_reset_bind(dev, ret, 12); 798 if (ret) 799 debug("Warning: software reset driver bind faile\n"); 800 #endif 801 802 return ret; 803 } 804 805 static const struct udevice_id rk3328_clk_ids[] = { 806 { .compatible = "rockchip,rk3328-cru" }, 807 { } 808 }; 809 810 U_BOOT_DRIVER(rockchip_rk3328_cru) = { 811 .name = "rockchip_rk3328_cru", 812 .id = UCLASS_CLK, 813 .of_match = rk3328_clk_ids, 814 .priv_auto_alloc_size = sizeof(struct rk3328_clk_priv), 815 .ofdata_to_platdata = rk3328_clk_ofdata_to_platdata, 816 .ops = &rk3328_clk_ops, 817 .bind = rk3328_clk_bind, 818 .probe = rk3328_clk_probe, 819 }; 820