1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd 4 */ 5 6 #include <common.h> 7 #include <bitfield.h> 8 #include <clk-uclass.h> 9 #include <dm.h> 10 #include <errno.h> 11 #include <syscon.h> 12 #include <clk.h> 13 #include <asm/arch/clock.h> 14 #include <asm/arch/cru_rk1808.h> 15 #include <asm/arch/hardware.h> 16 #include <asm/io.h> 17 #include <dm/lists.h> 18 #include <dt-bindings/clock/rk1808-cru.h> 19 #include <div64.h> 20 21 DECLARE_GLOBAL_DATA_PTR; 22 23 #define RK1808_CPUCLK_RATE(_rate, _aclk_div, _pclk_div) \ 24 { \ 25 .rate = _rate##U, \ 26 .aclk_div = _aclk_div, \ 27 .pclk_div = _pclk_div, \ 28 } 29 30 #define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1)) 31 32 static struct rockchip_pll_rate_table rk1808_pll_rates[] = { 33 /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */ 34 RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0), 35 RK3036_PLL_RATE(1188000000, 2, 99, 1, 1, 1, 0), 36 RK3036_PLL_RATE(1100000000, 12, 550, 1, 1, 1, 0), 37 RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0), 38 RK3036_PLL_RATE(1000000000, 6, 500, 2, 1, 1, 0), 39 RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0), 40 RK3036_PLL_RATE(800000000, 6, 400, 2, 1, 1, 0), 41 RK3036_PLL_RATE(600000000, 1, 75, 3, 1, 1, 0), 42 RK3036_PLL_RATE(594000000, 2, 99, 2, 1, 1, 0), 43 RK3036_PLL_RATE(500000000, 6, 250, 2, 1, 1, 0), 44 RK3036_PLL_RATE(200000000, 1, 200, 6, 4, 1, 0), 45 RK3036_PLL_RATE(100000000, 1, 150, 6, 6, 1, 0), 46 { /* sentinel */ }, 47 }; 48 49 #ifndef CONFIG_SPL_BUILD 50 #define RK1808_CLK_DUMP(_id, _name, _iscru) \ 51 { \ 52 .id = _id, \ 53 .name = _name, \ 54 .is_cru = _iscru, \ 55 } 56 57 static const struct rk1808_clk_info clks_dump[] = { 58 RK1808_CLK_DUMP(PLL_APLL, "apll", true), 59 RK1808_CLK_DUMP(PLL_DPLL, "dpll", true), 60 RK1808_CLK_DUMP(PLL_CPLL, "cpll", true), 61 RK1808_CLK_DUMP(PLL_GPLL, "gpll", true), 62 RK1808_CLK_DUMP(PLL_NPLL, "npll", true), 63 RK1808_CLK_DUMP(PLL_PPLL, "ppll", true), 64 RK1808_CLK_DUMP(HSCLK_BUS_PRE, "hsclk_bus", true), 65 RK1808_CLK_DUMP(MSCLK_BUS_PRE, "msclk_bus", true), 66 RK1808_CLK_DUMP(LSCLK_BUS_PRE, "lsclk_bus", true), 67 RK1808_CLK_DUMP(MSCLK_PERI, "msclk_peri", true), 68 RK1808_CLK_DUMP(LSCLK_PERI, "lsclk_peri", true), 69 }; 70 #endif 71 72 static struct rockchip_cpu_rate_table rk1808_cpu_rates[] = { 73 RK1808_CPUCLK_RATE(1200000000, 1, 5), 74 RK1808_CPUCLK_RATE(1008000000, 1, 5), 75 RK1808_CPUCLK_RATE(816000000, 1, 3), 76 RK1808_CPUCLK_RATE(600000000, 1, 3), 77 }; 78 79 static struct rockchip_pll_clock rk1808_pll_clks[] = { 80 [APLL] = PLL(pll_rk3036, PLL_APLL, RK1808_PLL_CON(0), 81 RK1808_MODE_CON, 0, 10, 0, rk1808_pll_rates), 82 [DPLL] = PLL(pll_rk3036, PLL_DPLL, RK1808_PLL_CON(8), 83 RK1808_MODE_CON, 2, 10, 0, NULL), 84 [CPLL] = PLL(pll_rk3036, PLL_CPLL, RK1808_PLL_CON(16), 85 RK1808_MODE_CON, 4, 10, 0, rk1808_pll_rates), 86 [GPLL] = PLL(pll_rk3036, PLL_GPLL, RK1808_PLL_CON(24), 87 RK1808_MODE_CON, 6, 10, 0, rk1808_pll_rates), 88 [NPLL] = PLL(pll_rk3036, PLL_NPLL, RK1808_PLL_CON(32), 89 RK1808_MODE_CON, 8, 10, 0, rk1808_pll_rates), 90 [PPLL] = PLL(pll_rk3036, PLL_PPLL, RK1808_PMU_PLL_CON(0), 91 RK1808_PMU_MODE_CON, 0, 10, 0, rk1808_pll_rates), 92 }; 93 94 #ifndef CONFIG_SPL_BUILD 95 static ulong rk1808_i2c_get_clk(struct rk1808_clk_priv *priv, ulong clk_id) 96 { 97 struct rk1808_cru *cru = priv->cru; 98 u32 div, con; 99 100 switch (clk_id) { 101 case SCLK_PMU_I2C0: 102 con = readl(&cru->pmu_clksel_con[7]); 103 div = (con & CLK_I2C0_DIV_CON_MASK) >> CLK_I2C0_DIV_CON_SHIFT; 104 break; 105 case SCLK_I2C1: 106 con = readl(&cru->clksel_con[59]); 107 div = (con & CLK_I2C1_DIV_CON_MASK) >> CLK_I2C1_DIV_CON_SHIFT; 108 break; 109 case SCLK_I2C2: 110 con = readl(&cru->clksel_con[59]); 111 div = (con & CLK_I2C2_DIV_CON_MASK) >> CLK_I2C2_DIV_CON_SHIFT; 112 break; 113 case SCLK_I2C3: 114 con = readl(&cru->clksel_con[60]); 115 div = (con & CLK_I2C3_DIV_CON_MASK) >> CLK_I2C3_DIV_CON_SHIFT; 116 break; 117 case SCLK_I2C4: 118 con = readl(&cru->clksel_con[71]); 119 div = (con & CLK_I2C4_DIV_CON_MASK) >> CLK_I2C4_DIV_CON_SHIFT; 120 break; 121 case SCLK_I2C5: 122 con = readl(&cru->clksel_con[71]); 123 div = (con & CLK_I2C5_DIV_CON_MASK) >> CLK_I2C5_DIV_CON_SHIFT; 124 break; 125 default: 126 printf("do not support this i2c bus\n"); 127 return -EINVAL; 128 } 129 130 return DIV_TO_RATE(priv->gpll_hz, div); 131 } 132 133 static ulong rk1808_i2c_set_clk(struct rk1808_clk_priv *priv, 134 ulong clk_id, uint hz) 135 { 136 struct rk1808_cru *cru = priv->cru; 137 int src_clk_div; 138 139 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz); 140 assert(src_clk_div - 1 < 127); 141 142 switch (clk_id) { 143 case SCLK_PMU_I2C0: 144 rk_clrsetreg(&cru->pmu_clksel_con[7], 145 CLK_I2C0_DIV_CON_MASK | CLK_I2C0_PLL_SEL_MASK, 146 (src_clk_div - 1) << CLK_I2C0_DIV_CON_SHIFT | 147 CLK_I2C0_PLL_SEL_PPLL << CLK_I2C0_PLL_SEL_SHIFT); 148 break; 149 case SCLK_I2C1: 150 rk_clrsetreg(&cru->clksel_con[59], 151 CLK_I2C1_DIV_CON_MASK | CLK_I2C1_PLL_SEL_MASK, 152 (src_clk_div - 1) << CLK_I2C1_DIV_CON_SHIFT | 153 CLK_I2C_PLL_SEL_GPLL << CLK_I2C1_PLL_SEL_SHIFT); 154 break; 155 case SCLK_I2C2: 156 rk_clrsetreg(&cru->clksel_con[59], 157 CLK_I2C2_DIV_CON_MASK | CLK_I2C2_PLL_SEL_MASK, 158 (src_clk_div - 1) << CLK_I2C2_DIV_CON_SHIFT | 159 CLK_I2C_PLL_SEL_GPLL << CLK_I2C2_PLL_SEL_SHIFT); 160 break; 161 case SCLK_I2C3: 162 rk_clrsetreg(&cru->clksel_con[60], 163 CLK_I2C3_DIV_CON_MASK | CLK_I2C3_PLL_SEL_MASK, 164 (src_clk_div - 1) << CLK_I2C3_DIV_CON_SHIFT | 165 CLK_I2C_PLL_SEL_GPLL << CLK_I2C3_PLL_SEL_SHIFT); 166 break; 167 case SCLK_I2C4: 168 rk_clrsetreg(&cru->clksel_con[71], 169 CLK_I2C4_DIV_CON_MASK | CLK_I2C4_PLL_SEL_MASK, 170 (src_clk_div - 1) << CLK_I2C4_DIV_CON_SHIFT | 171 CLK_I2C_PLL_SEL_GPLL << CLK_I2C4_PLL_SEL_SHIFT); 172 break; 173 case SCLK_I2C5: 174 rk_clrsetreg(&cru->clksel_con[71], 175 CLK_I2C5_DIV_CON_MASK | CLK_I2C5_PLL_SEL_MASK, 176 (src_clk_div - 1) << CLK_I2C5_DIV_CON_SHIFT | 177 CLK_I2C_PLL_SEL_GPLL << CLK_I2C5_PLL_SEL_SHIFT); 178 break; 179 default: 180 printf("do not support this i2c bus\n"); 181 return -EINVAL; 182 } 183 184 return rk1808_i2c_get_clk(priv, clk_id); 185 } 186 #endif 187 188 static ulong rk1808_mmc_get_clk(struct rk1808_clk_priv *priv, uint clk_id) 189 { 190 struct rk1808_cru *cru = priv->cru; 191 u32 div, con, con_id; 192 193 switch (clk_id) { 194 case HCLK_SDMMC: 195 case SCLK_SDMMC: 196 con_id = 20; 197 break; 198 case HCLK_SDIO: 199 case SCLK_SDIO: 200 con_id = 22; 201 break; 202 case HCLK_EMMC: 203 case SCLK_EMMC: 204 case SCLK_EMMC_SAMPLE: 205 con_id = 24; 206 break; 207 default: 208 return -EINVAL; 209 } 210 211 con = readl(&cru->clksel_con[con_id]); 212 div = (con & EMMC_DIV_MASK) >> EMMC_DIV_SHIFT; 213 214 if ((con & EMMC_PLL_MASK) >> EMMC_PLL_SHIFT 215 == EMMC_SEL_24M) 216 return DIV_TO_RATE(OSC_HZ, div) / 2; 217 else 218 return DIV_TO_RATE(priv->gpll_hz, div) / 2; 219 } 220 221 static ulong rk1808_mmc_set_clk(struct rk1808_clk_priv *priv, 222 ulong clk_id, ulong set_rate) 223 { 224 struct rk1808_cru *cru = priv->cru; 225 int src_clk_div; 226 u32 con_id; 227 228 switch (clk_id) { 229 case HCLK_SDMMC: 230 case SCLK_SDMMC: 231 con_id = 20; 232 break; 233 case HCLK_SDIO: 234 case SCLK_SDIO: 235 con_id = 22; 236 break; 237 case HCLK_EMMC: 238 case SCLK_EMMC: 239 con_id = 24; 240 break; 241 default: 242 return -EINVAL; 243 } 244 245 /* Select clk_sdmmc/emmc source from GPLL by default */ 246 /* mmc clock defaulg div 2 internal, need provide double in cru */ 247 src_clk_div = DIV_ROUND_UP(priv->gpll_hz / 2, set_rate); 248 249 if (src_clk_div > 127) { 250 /* use 24MHz source for 400KHz clock */ 251 src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, set_rate); 252 rk_clrsetreg(&cru->clksel_con[con_id], 253 EMMC_PLL_MASK | EMMC_DIV_MASK, 254 EMMC_SEL_24M << EMMC_PLL_SHIFT | 255 (src_clk_div - 1) << EMMC_DIV_SHIFT); 256 } else { 257 rk_clrsetreg(&cru->clksel_con[con_id], 258 EMMC_PLL_MASK | EMMC_DIV_MASK, 259 EMMC_SEL_GPLL << EMMC_PLL_SHIFT | 260 (src_clk_div - 1) << EMMC_DIV_SHIFT); 261 } 262 rk_clrsetreg(&cru->clksel_con[con_id + 1], EMMC_CLK_SEL_MASK, 263 EMMC_CLK_SEL_EMMC); 264 265 return rk1808_mmc_get_clk(priv, clk_id); 266 } 267 268 static ulong rk1808_sfc_get_clk(struct rk1808_clk_priv *priv, uint clk_id) 269 { 270 struct rk1808_cru *cru = priv->cru; 271 u32 div, con; 272 273 con = readl(&cru->clksel_con[26]); 274 div = (con & SFC_DIV_CON_MASK) >> SFC_DIV_CON_SHIFT; 275 276 return DIV_TO_RATE(priv->gpll_hz, div); 277 } 278 279 static ulong rk1808_sfc_set_clk(struct rk1808_clk_priv *priv, 280 ulong clk_id, ulong set_rate) 281 { 282 struct rk1808_cru *cru = priv->cru; 283 int src_clk_div; 284 285 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, set_rate); 286 rk_clrsetreg(&cru->clksel_con[26], 287 SFC_PLL_SEL_MASK | SFC_DIV_CON_MASK, 288 0 << SFC_PLL_SEL_SHIFT | 289 (src_clk_div - 1) << SFC_DIV_CON_SHIFT); 290 291 return rk1808_sfc_get_clk(priv, clk_id); 292 } 293 294 static ulong rk1808_saradc_get_clk(struct rk1808_clk_priv *priv) 295 { 296 struct rk1808_cru *cru = priv->cru; 297 u32 div, con; 298 299 con = readl(&cru->clksel_con[63]); 300 div = con & CLK_SARADC_DIV_CON_MASK; 301 302 return DIV_TO_RATE(OSC_HZ, div); 303 } 304 305 static ulong rk1808_saradc_set_clk(struct rk1808_clk_priv *priv, uint hz) 306 { 307 struct rk1808_cru *cru = priv->cru; 308 int src_clk_div; 309 310 src_clk_div = DIV_ROUND_UP(OSC_HZ, hz); 311 assert(src_clk_div - 1 < 2047); 312 313 rk_clrsetreg(&cru->clksel_con[63], 314 CLK_SARADC_DIV_CON_MASK, 315 (src_clk_div - 1) << CLK_SARADC_DIV_CON_SHIFT); 316 317 return rk1808_saradc_get_clk(priv); 318 } 319 320 #ifndef CONFIG_SPL_BUILD 321 static ulong rk1808_pwm_get_clk(struct rk1808_clk_priv *priv, ulong clk_id) 322 { 323 struct rk1808_cru *cru = priv->cru; 324 u32 div, con; 325 326 switch (clk_id) { 327 case SCLK_PWM0: 328 con = readl(&cru->clksel_con[69]); 329 div = (con & CLK_PWM0_DIV_CON_MASK) >> CLK_PWM0_DIV_CON_SHIFT; 330 break; 331 case SCLK_PWM1: 332 con = readl(&cru->clksel_con[69]); 333 div = (con & CLK_PWM1_DIV_CON_MASK) >> CLK_PWM1_DIV_CON_SHIFT; 334 break; 335 case SCLK_PWM2: 336 con = readl(&cru->clksel_con[70]); 337 div = (con & CLK_PWM2_DIV_CON_MASK) >> CLK_PWM2_DIV_CON_SHIFT; 338 break; 339 default: 340 printf("do not support this pwm bus\n"); 341 return -EINVAL; 342 } 343 344 return DIV_TO_RATE(priv->gpll_hz, div); 345 } 346 347 static ulong rk1808_pwm_set_clk(struct rk1808_clk_priv *priv, 348 ulong clk_id, uint hz) 349 { 350 struct rk1808_cru *cru = priv->cru; 351 int src_clk_div; 352 353 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz); 354 assert(src_clk_div - 1 < 127); 355 356 switch (clk_id) { 357 case SCLK_PWM0: 358 rk_clrsetreg(&cru->clksel_con[69], 359 CLK_PWM0_DIV_CON_MASK | CLK_PWM0_PLL_SEL_MASK, 360 (src_clk_div - 1) << CLK_PWM0_DIV_CON_SHIFT | 361 CLK_PWM_PLL_SEL_GPLL << CLK_PWM0_PLL_SEL_SHIFT); 362 break; 363 case SCLK_PWM1: 364 rk_clrsetreg(&cru->clksel_con[69], 365 CLK_PWM1_DIV_CON_MASK | CLK_PWM1_PLL_SEL_MASK, 366 (src_clk_div - 1) << CLK_PWM1_DIV_CON_SHIFT | 367 CLK_PWM_PLL_SEL_GPLL << CLK_PWM1_PLL_SEL_SHIFT); 368 break; 369 case SCLK_PWM2: 370 rk_clrsetreg(&cru->clksel_con[70], 371 CLK_PWM2_DIV_CON_MASK | CLK_PWM2_PLL_SEL_MASK, 372 (src_clk_div - 1) << CLK_PWM2_DIV_CON_SHIFT | 373 CLK_PWM_PLL_SEL_GPLL << CLK_PWM2_PLL_SEL_SHIFT); 374 break; 375 default: 376 printf("do not support this pwm bus\n"); 377 return -EINVAL; 378 } 379 380 return rk1808_pwm_get_clk(priv, clk_id); 381 } 382 383 static ulong rk1808_tsadc_get_clk(struct rk1808_clk_priv *priv) 384 { 385 struct rk1808_cru *cru = priv->cru; 386 u32 div, con; 387 388 con = readl(&cru->clksel_con[62]); 389 div = con & CLK_SARADC_DIV_CON_MASK; 390 391 return DIV_TO_RATE(OSC_HZ, div); 392 } 393 394 static ulong rk1808_tsadc_set_clk(struct rk1808_clk_priv *priv, uint hz) 395 { 396 struct rk1808_cru *cru = priv->cru; 397 int src_clk_div; 398 399 src_clk_div = DIV_ROUND_UP(OSC_HZ, hz); 400 assert(src_clk_div - 1 < 2047); 401 402 rk_clrsetreg(&cru->clksel_con[62], 403 CLK_SARADC_DIV_CON_MASK, 404 (src_clk_div - 1) << CLK_SARADC_DIV_CON_SHIFT); 405 406 return rk1808_tsadc_get_clk(priv); 407 } 408 409 static ulong rk1808_spi_get_clk(struct rk1808_clk_priv *priv, ulong clk_id) 410 { 411 struct rk1808_cru *cru = priv->cru; 412 u32 div, con; 413 414 switch (clk_id) { 415 case SCLK_SPI0: 416 con = readl(&cru->clksel_con[60]); 417 div = (con & CLK_SPI0_DIV_CON_MASK) >> CLK_SPI0_DIV_CON_SHIFT; 418 break; 419 case SCLK_SPI1: 420 con = readl(&cru->clksel_con[61]); 421 div = (con & CLK_SPI1_DIV_CON_MASK) >> CLK_SPI1_DIV_CON_SHIFT; 422 break; 423 case SCLK_SPI2: 424 con = readl(&cru->clksel_con[61]); 425 div = (con & CLK_SPI2_DIV_CON_MASK) >> CLK_SPI2_DIV_CON_SHIFT; 426 break; 427 default: 428 printf("do not support this pwm bus\n"); 429 return -EINVAL; 430 } 431 432 return DIV_TO_RATE(priv->gpll_hz, div); 433 } 434 435 static ulong rk1808_spi_set_clk(struct rk1808_clk_priv *priv, 436 ulong clk_id, uint hz) 437 { 438 struct rk1808_cru *cru = priv->cru; 439 int src_clk_div; 440 441 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz); 442 assert(src_clk_div - 1 < 127); 443 444 switch (clk_id) { 445 case SCLK_SPI0: 446 rk_clrsetreg(&cru->clksel_con[60], 447 CLK_SPI0_DIV_CON_MASK | CLK_SPI0_PLL_SEL_MASK, 448 (src_clk_div - 1) << CLK_SPI0_DIV_CON_SHIFT | 449 CLK_SPI_PLL_SEL_GPLL << CLK_SPI0_PLL_SEL_SHIFT); 450 break; 451 case SCLK_SPI1: 452 rk_clrsetreg(&cru->clksel_con[61], 453 CLK_SPI1_DIV_CON_MASK | CLK_SPI1_PLL_SEL_MASK, 454 (src_clk_div - 1) << CLK_SPI1_DIV_CON_SHIFT | 455 CLK_SPI_PLL_SEL_GPLL << CLK_SPI1_PLL_SEL_SHIFT); 456 break; 457 case SCLK_SPI2: 458 rk_clrsetreg(&cru->clksel_con[61], 459 CLK_SPI2_DIV_CON_MASK | CLK_SPI2_PLL_SEL_MASK, 460 (src_clk_div - 1) << CLK_SPI2_DIV_CON_SHIFT | 461 CLK_SPI_PLL_SEL_GPLL << CLK_SPI2_PLL_SEL_SHIFT); 462 break; 463 default: 464 printf("do not support this pwm bus\n"); 465 return -EINVAL; 466 } 467 468 return rk1808_spi_get_clk(priv, clk_id); 469 } 470 471 #define RK1808_VOP_PLL_LIMIT_FREQ 600 * 1000000 472 static ulong rk1808_vop_get_clk(struct rk1808_clk_priv *priv, ulong clk_id) 473 { 474 struct rk1808_cru *cru = priv->cru; 475 u32 div, con, parent; 476 477 switch (clk_id) { 478 case ACLK_VOPRAW: 479 case ACLK_VOPLITE: 480 con = readl(&cru->clksel_con[4]); 481 div = (con & ACLK_VOP_DIV_CON_MASK) >> ACLK_VOP_DIV_CON_SHIFT; 482 parent = priv->gpll_hz; 483 break; 484 case HCLK_VOPRAW: 485 case HCLK_VOPLITE: 486 parent = rk1808_vop_get_clk(priv, ACLK_VOPRAW); 487 con = readl(&cru->clksel_con[4]); 488 div = (con & HCLK_VOP_DIV_CON_MASK) >> HCLK_VOP_DIV_CON_SHIFT; 489 break; 490 case DCLK_VOPRAW: 491 con = readl(&cru->clksel_con[5]); 492 div = con & DCLK_VOPRAW_DIV_CON_MASK; 493 parent = rockchip_pll_get_rate(&rk1808_pll_clks[NPLL], 494 priv->cru, NPLL); 495 break; 496 case DCLK_VOPLITE: 497 con = readl(&cru->clksel_con[7]); 498 div = con & DCLK_VOPLITE_DIV_CON_MASK; 499 parent = (con & DCLK_VOPLITE_PLL_SEL_MASK) >> 500 DCLK_VOPLITE_PLL_SEL_SHIFT; 501 if (parent == DCLK_VOPLITE_PLL_SEL_NPLL) 502 parent = rockchip_pll_get_rate(&rk1808_pll_clks[NPLL], 503 priv->cru, NPLL); 504 else if (parent == DCLK_VOPLITE_PLL_SEL_CPLL) 505 parent = priv->cpll_hz; 506 else 507 parent = priv->gpll_hz; 508 break; 509 default: 510 return -ENOENT; 511 } 512 513 return DIV_TO_RATE(parent, div); 514 } 515 516 static ulong rk1808_vop_set_clk(struct rk1808_clk_priv *priv, 517 ulong clk_id, uint hz) 518 { 519 struct rk1808_cru *cru = priv->cru; 520 int src_clk_div, parent; 521 522 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz); 523 assert(src_clk_div - 1 < 31); 524 525 switch (clk_id) { 526 case ACLK_VOPRAW: 527 case ACLK_VOPLITE: 528 rk_clrsetreg(&cru->clksel_con[4], 529 ACLK_VOP_PLL_SEL_MASK | ACLK_VOP_DIV_CON_MASK, 530 ACLK_VOP_PLL_SEL_GPLL << ACLK_VOP_PLL_SEL_SHIFT | 531 (src_clk_div - 1) << ACLK_VOP_DIV_CON_SHIFT); 532 break; 533 case HCLK_VOPRAW: 534 case HCLK_VOPLITE: 535 src_clk_div = 536 DIV_ROUND_UP(rk1808_vop_get_clk(priv, ACLK_VOPRAW), hz); 537 assert(src_clk_div - 1 < 15); 538 rk_clrsetreg(&cru->clksel_con[4], 539 HCLK_VOP_DIV_CON_MASK, 540 (src_clk_div - 1) << HCLK_VOP_DIV_CON_SHIFT); 541 break; 542 case DCLK_VOPRAW: 543 /* 544 * vopb dclk source from npll, and equals to 545 */ 546 src_clk_div = DIV_ROUND_UP(RK1808_VOP_PLL_LIMIT_FREQ, hz); 547 rk_clrsetreg(&cru->clksel_con[5], 548 DCLK_VOPRAW_SEL_MASK | 549 DCLK_VOPRAW_PLL_SEL_MASK | 550 DCLK_VOPRAW_DIV_CON_MASK, 551 (DCLK_VOPRAW_SEL_VOPRAW << 552 DCLK_VOPRAW_SEL_SHIFT) | 553 (DCLK_VOPRAW_PLL_SEL_NPLL << 554 DCLK_VOPRAW_PLL_SEL_SHIFT) | 555 ((src_clk_div - 1) << DCLK_VOPRAW_DIV_CON_SHIFT)); 556 rockchip_pll_set_rate(&rk1808_pll_clks[NPLL], 557 priv->cru, NPLL, src_clk_div * hz); 558 559 break; 560 case DCLK_VOPLITE: 561 /* 562 * vopl dclk source from cpll, and equals to 563 */ 564 if (!(priv->cpll_hz % hz)) { 565 parent = DCLK_VOPLITE_PLL_SEL_CPLL; 566 src_clk_div = DIV_ROUND_UP(priv->cpll_hz, hz); 567 } else if (!(priv->gpll_hz % hz)) { 568 parent = DCLK_VOPLITE_PLL_SEL_GPLL; 569 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz); 570 } else { 571 parent = DCLK_VOPLITE_PLL_SEL_NPLL; 572 src_clk_div = DIV_ROUND_UP(RK1808_VOP_PLL_LIMIT_FREQ, 573 hz); 574 rockchip_pll_set_rate(&rk1808_pll_clks[NPLL], 575 priv->cru, NPLL, 576 src_clk_div * hz); 577 } 578 rk_clrsetreg(&cru->clksel_con[7], 579 DCLK_VOPLITE_SEL_MASK | DCLK_VOPLITE_PLL_SEL_MASK | 580 DCLK_VOPLITE_DIV_CON_MASK, 581 (DCLK_VOPLITE_SEL_VOPRAW << 582 DCLK_VOPLITE_SEL_SHIFT) | 583 (parent << DCLK_VOPLITE_PLL_SEL_SHIFT) | 584 ((src_clk_div - 1) << DCLK_VOPLITE_DIV_CON_SHIFT)); 585 break; 586 default: 587 printf("do not support this vop freq\n"); 588 return -EINVAL; 589 } 590 591 return rk1808_vop_get_clk(priv, clk_id); 592 } 593 594 static ulong rk1808_mac_set_clk(struct clk *clk, uint hz) 595 { 596 struct rk1808_clk_priv *priv = dev_get_priv(clk->dev); 597 struct rk1808_cru *cru = priv->cru; 598 u32 con = readl(&cru->clksel_con[26]); 599 ulong pll_rate; 600 u8 div; 601 602 if ((con >> GMAC_PLL_SEL_SHIFT) & GMAC_PLL_SEL_NPLL) 603 pll_rate = rockchip_pll_get_rate(&rk1808_pll_clks[NPLL], 604 priv->cru, NPLL); 605 else if ((con >> GMAC_PLL_SEL_SHIFT) & GMAC_PLL_SEL_PPLL) 606 pll_rate = rockchip_pll_get_rate(&rk1808_pll_clks[PPLL], 607 priv->cru, PPLL); 608 else 609 pll_rate = rockchip_pll_get_rate(&rk1808_pll_clks[CPLL], 610 priv->cru, CPLL); 611 612 /*default set 50MHZ for gmac*/ 613 if (!hz) 614 hz = 50000000; 615 616 div = DIV_ROUND_UP(pll_rate, hz) - 1; 617 assert(div < 32); 618 rk_clrsetreg(&cru->clksel_con[26], CLK_GMAC_DIV_MASK, 619 div << CLK_GMAC_DIV_SHIFT); 620 621 return DIV_TO_RATE(pll_rate, div); 622 } 623 624 static int rk1808_mac_set_speed_clk(struct clk *clk, ulong clk_id, uint hz) 625 { 626 struct rk1808_clk_priv *priv = dev_get_priv(clk->dev); 627 struct rk1808_cru *cru = priv->cru; 628 u32 sel; 629 630 switch (clk_id) { 631 case SCLK_GMAC_RGMII_SPEED: 632 if (hz == 125000000) 633 sel = 0; 634 else if (hz == 2500000) 635 sel = 2; 636 else 637 sel = 3; 638 rk_clrsetreg(&cru->clksel_con[27], RGMII_CLK_SEL_MASK, 639 sel << RGMII_CLK_SEL_SHIFT); 640 break; 641 case SCLK_GMAC_RMII_SPEED: 642 if (hz == 2500000) 643 sel = 0; 644 else 645 sel = 1; 646 rk_clrsetreg(&cru->clksel_con[27], RMII_CLK_SEL_MASK, 647 sel << RMII_CLK_SEL_SHIFT); 648 break; 649 default: 650 return -ENOENT; 651 } 652 return 0; 653 } 654 655 static ulong rk1808_crypto_get_clk(struct rk1808_clk_priv *priv, ulong clk_id) 656 { 657 struct rk1808_cru *cru = priv->cru; 658 u32 div, con, parent; 659 660 switch (clk_id) { 661 case SCLK_CRYPTO: 662 con = readl(&cru->clksel_con[29]); 663 div = (con & CRYPTO_DIV_MASK) >> CRYPTO_DIV_SHIFT; 664 parent = priv->gpll_hz; 665 break; 666 case SCLK_CRYPTO_APK: 667 con = readl(&cru->clksel_con[29]); 668 div = (con & CRYPTO_APK_DIV_MASK) >> CRYPTO_APK_DIV_SHIFT; 669 parent = priv->gpll_hz; 670 break; 671 default: 672 return -ENOENT; 673 } 674 675 return DIV_TO_RATE(parent, div); 676 } 677 678 static ulong rk1808_crypto_set_clk(struct rk1808_clk_priv *priv, ulong clk_id, 679 ulong hz) 680 { 681 struct rk1808_cru *cru = priv->cru; 682 int src_clk_div; 683 684 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz); 685 assert(src_clk_div - 1 <= 31); 686 687 /* 688 * select gpll as crypto clock source and 689 * set up dependent divisors for crypto clocks. 690 */ 691 switch (clk_id) { 692 case SCLK_CRYPTO: 693 rk_clrsetreg(&cru->clksel_con[29], 694 CRYPTO_PLL_SEL_MASK | CRYPTO_DIV_MASK, 695 CRYPTO_PLL_SEL_GPLL << CRYPTO_PLL_SEL_SHIFT | 696 (src_clk_div - 1) << CRYPTO_DIV_SHIFT); 697 break; 698 case SCLK_CRYPTO_APK: 699 rk_clrsetreg(&cru->clksel_con[29], 700 CRYPTO_APK_PLL_SEL_MASK | CRYPTO_APK_DIV_MASK, 701 CRYPTO_PLL_SEL_GPLL << CRYPTO_APK_SEL_SHIFT | 702 (src_clk_div - 1) << CRYPTO_APK_DIV_SHIFT); 703 break; 704 default: 705 printf("do not support this peri freq\n"); 706 return -EINVAL; 707 } 708 709 return rk1808_crypto_get_clk(priv, clk_id); 710 } 711 #endif 712 713 static ulong rk1808_bus_get_clk(struct rk1808_clk_priv *priv, ulong clk_id) 714 { 715 struct rk1808_cru *cru = priv->cru; 716 u32 div, con, parent; 717 718 switch (clk_id) { 719 case HSCLK_BUS_PRE: 720 con = readl(&cru->clksel_con[27]); 721 div = (con & HSCLK_BUS_DIV_CON_MASK) >> HSCLK_BUS_DIV_CON_SHIFT; 722 parent = priv->gpll_hz; 723 break; 724 case MSCLK_BUS_PRE: 725 con = readl(&cru->clksel_con[28]); 726 div = (con & MSCLK_BUS_DIV_CON_MASK) >> MSCLK_BUS_DIV_CON_SHIFT; 727 parent = priv->gpll_hz; 728 break; 729 case LSCLK_BUS_PRE: 730 case PCLK_WDT: 731 con = readl(&cru->clksel_con[28]); 732 div = (con & LSCLK_BUS_DIV_CON_MASK) >> LSCLK_BUS_DIV_CON_SHIFT; 733 parent = priv->gpll_hz; 734 break; 735 default: 736 return -ENOENT; 737 } 738 739 return DIV_TO_RATE(parent, div); 740 } 741 742 static ulong rk1808_bus_set_clk(struct rk1808_clk_priv *priv, 743 ulong clk_id, ulong hz) 744 { 745 struct rk1808_cru *cru = priv->cru; 746 int src_clk_div; 747 748 /* 749 * select gpll as pd_bus bus clock source and 750 * set up dependent divisors for PCLK/HCLK and ACLK clocks. 751 */ 752 switch (clk_id) { 753 case HSCLK_BUS_PRE: 754 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz); 755 assert(src_clk_div - 1 < 31); 756 rk_clrsetreg(&cru->clksel_con[27], 757 CLK_BUS_PLL_SEL_MASK | HSCLK_BUS_DIV_CON_MASK, 758 CLK_BUS_PLL_SEL_GPLL << CLK_BUS_PLL_SEL_SHIFT | 759 (src_clk_div - 1) << HSCLK_BUS_DIV_CON_SHIFT); 760 break; 761 case MSCLK_BUS_PRE: 762 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz); 763 assert(src_clk_div - 1 < 31); 764 rk_clrsetreg(&cru->clksel_con[28], 765 CLK_BUS_PLL_SEL_MASK | MSCLK_BUS_DIV_CON_MASK, 766 CLK_BUS_PLL_SEL_GPLL << CLK_BUS_PLL_SEL_SHIFT | 767 (src_clk_div - 1) << MSCLK_BUS_DIV_CON_SHIFT); 768 break; 769 case LSCLK_BUS_PRE: 770 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz); 771 assert(src_clk_div - 1 < 31); 772 rk_clrsetreg(&cru->clksel_con[28], 773 CLK_BUS_PLL_SEL_MASK | LSCLK_BUS_DIV_CON_MASK, 774 CLK_BUS_PLL_SEL_GPLL << CLK_BUS_PLL_SEL_SHIFT | 775 (src_clk_div - 1) << LSCLK_BUS_DIV_CON_SHIFT); 776 break; 777 default: 778 printf("do not support this bus freq\n"); 779 return -EINVAL; 780 } 781 782 return rk1808_bus_get_clk(priv, clk_id); 783 } 784 785 static ulong rk1808_peri_get_clk(struct rk1808_clk_priv *priv, ulong clk_id) 786 { 787 struct rk1808_cru *cru = priv->cru; 788 u32 div, con, parent; 789 790 switch (clk_id) { 791 case MSCLK_PERI: 792 con = readl(&cru->clksel_con[19]); 793 div = (con & MSCLK_PERI_DIV_CON_MASK) >> 794 MSCLK_PERI_DIV_CON_SHIFT; 795 parent = priv->gpll_hz; 796 break; 797 case LSCLK_PERI: 798 con = readl(&cru->clksel_con[19]); 799 div = (con & LSCLK_PERI_DIV_CON_MASK) >> 800 LSCLK_PERI_DIV_CON_SHIFT; 801 parent = priv->gpll_hz; 802 break; 803 default: 804 return -ENOENT; 805 } 806 807 return DIV_TO_RATE(parent, div); 808 } 809 810 static ulong rk1808_peri_set_clk(struct rk1808_clk_priv *priv, 811 ulong clk_id, ulong hz) 812 { 813 struct rk1808_cru *cru = priv->cru; 814 int src_clk_div; 815 816 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz); 817 assert(src_clk_div - 1 < 31); 818 819 /* 820 * select gpll as pd_peri bus clock source and 821 * set up dependent divisors for HCLK and ACLK clocks. 822 */ 823 switch (clk_id) { 824 case MSCLK_PERI: 825 rk_clrsetreg(&cru->clksel_con[19], 826 CLK_PERI_PLL_SEL_MASK | MSCLK_PERI_DIV_CON_MASK, 827 CLK_PERI_PLL_SEL_GPLL << CLK_PERI_PLL_SEL_SHIFT | 828 (src_clk_div - 1) << MSCLK_PERI_DIV_CON_SHIFT); 829 break; 830 case LSCLK_PERI: 831 rk_clrsetreg(&cru->clksel_con[19], 832 CLK_PERI_PLL_SEL_MASK | LSCLK_PERI_DIV_CON_MASK, 833 CLK_PERI_PLL_SEL_GPLL << CLK_PERI_PLL_SEL_SHIFT | 834 (src_clk_div - 1) << LSCLK_PERI_DIV_CON_SHIFT); 835 break; 836 default: 837 printf("do not support this peri freq\n"); 838 return -EINVAL; 839 } 840 841 return rk1808_peri_get_clk(priv, clk_id); 842 } 843 844 static ulong rk1808_pclk_pmu_set_clk(struct rk1808_clk_priv *priv, 845 ulong clk_id, ulong parent_hz, ulong hz) 846 { 847 struct rk1808_cru *cru = priv->cru; 848 int src_clk_div; 849 850 src_clk_div = DIV_ROUND_UP(parent_hz, hz); 851 assert(src_clk_div - 1 < 31); 852 853 rk_clrsetreg(&cru->pmu_clksel_con[0], 854 PCLK_PMU_DIV_CON_MASK, 855 (src_clk_div - 1) << PCLK_PMU_DIV_CON_SHIFT); 856 857 return parent_hz / src_clk_div; 858 } 859 860 static ulong rk1808_armclk_set_clk(struct rk1808_clk_priv *priv, ulong hz) 861 { 862 struct rk1808_cru *cru = priv->cru; 863 const struct rockchip_cpu_rate_table *rate; 864 ulong old_rate; 865 866 rate = rockchip_get_cpu_settings(rk1808_cpu_rates, hz); 867 if (!rate) { 868 printf("%s unsupported rate\n", __func__); 869 return -EINVAL; 870 } 871 872 /* 873 * select apll as cpu/core clock pll source and 874 * set up dependent divisors for PERI and ACLK clocks. 875 * core hz : apll = 1:1 876 */ 877 old_rate = rockchip_pll_get_rate(&rk1808_pll_clks[APLL], 878 priv->cru, APLL); 879 if (old_rate > hz) { 880 if (rockchip_pll_set_rate(&rk1808_pll_clks[APLL], 881 priv->cru, APLL, hz)) 882 return -EINVAL; 883 rk_clrsetreg(&cru->clksel_con[0], 884 CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK | 885 CORE_ACLK_DIV_MASK | CORE_DBG_DIV_MASK, 886 rate->aclk_div << CORE_ACLK_DIV_SHIFT | 887 rate->pclk_div << CORE_DBG_DIV_SHIFT | 888 CORE_CLK_PLL_SEL_APLL << CORE_CLK_PLL_SEL_SHIFT | 889 0 << CORE_DIV_CON_SHIFT); 890 } else if (old_rate < hz) { 891 rk_clrsetreg(&cru->clksel_con[0], 892 CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK | 893 CORE_ACLK_DIV_MASK | CORE_DBG_DIV_MASK, 894 rate->aclk_div << CORE_ACLK_DIV_SHIFT | 895 rate->pclk_div << CORE_DBG_DIV_SHIFT | 896 CORE_CLK_PLL_SEL_APLL << CORE_CLK_PLL_SEL_SHIFT | 897 0 << CORE_DIV_CON_SHIFT); 898 if (rockchip_pll_set_rate(&rk1808_pll_clks[APLL], 899 priv->cru, APLL, hz)) 900 return -EINVAL; 901 } 902 903 return rockchip_pll_get_rate(&rk1808_pll_clks[APLL], priv->cru, APLL); 904 } 905 906 static ulong rk1808_clk_get_rate(struct clk *clk) 907 { 908 struct rk1808_clk_priv *priv = dev_get_priv(clk->dev); 909 ulong rate = 0; 910 911 debug("%s %ld\n", __func__, clk->id); 912 switch (clk->id) { 913 case PLL_APLL: 914 case PLL_DPLL: 915 case PLL_CPLL: 916 case PLL_GPLL: 917 case PLL_NPLL: 918 case PLL_PPLL: 919 rate = rockchip_pll_get_rate(&rk1808_pll_clks[clk->id - 1], 920 priv->cru, clk->id - 1); 921 break; 922 case ARMCLK: 923 rate = rockchip_pll_get_rate(&rk1808_pll_clks[APLL], 924 priv->cru, APLL); 925 break; 926 case HCLK_SDMMC: 927 case HCLK_EMMC: 928 case HCLK_SDIO: 929 case SCLK_SDMMC: 930 case SCLK_EMMC: 931 case SCLK_EMMC_SAMPLE: 932 case SCLK_SDIO: 933 rate = rk1808_mmc_get_clk(priv, clk->id); 934 break; 935 case SCLK_SFC: 936 rate = rk1808_sfc_get_clk(priv, clk->id); 937 break; 938 case SCLK_SARADC: 939 rate = rk1808_saradc_get_clk(priv); 940 break; 941 #ifndef CONFIG_SPL_BUILD 942 case SCLK_PMU_I2C0: 943 case SCLK_I2C1: 944 case SCLK_I2C2: 945 case SCLK_I2C3: 946 case SCLK_I2C4: 947 case SCLK_I2C5: 948 rate = rk1808_i2c_get_clk(priv, clk->id); 949 break; 950 case SCLK_PWM0: 951 case SCLK_PWM1: 952 case SCLK_PWM2: 953 rate = rk1808_pwm_get_clk(priv, clk->id); 954 break; 955 case SCLK_TSADC: 956 rate = rk1808_tsadc_get_clk(priv); 957 break; 958 case SCLK_SPI0: 959 case SCLK_SPI1: 960 case SCLK_SPI2: 961 rate = rk1808_spi_get_clk(priv, clk->id); 962 break; 963 case ACLK_VOPRAW: 964 case DCLK_VOPRAW: 965 case ACLK_VOPLITE: 966 case DCLK_VOPLITE: 967 rate = rk1808_vop_get_clk(priv, clk->id); 968 break; 969 case SCLK_CRYPTO: 970 case SCLK_CRYPTO_APK: 971 rate = rk1808_crypto_get_clk(priv, clk->id); 972 break; 973 #endif 974 case HSCLK_BUS_PRE: 975 case MSCLK_BUS_PRE: 976 case LSCLK_BUS_PRE: 977 case PCLK_WDT: 978 rate = rk1808_bus_get_clk(priv, clk->id); 979 break; 980 case MSCLK_PERI: 981 case LSCLK_PERI: 982 rate = rk1808_peri_get_clk(priv, clk->id); 983 break; 984 default: 985 return -ENOENT; 986 } 987 988 return rate; 989 } 990 991 static ulong rk1808_clk_set_rate(struct clk *clk, ulong rate) 992 { 993 struct rk1808_clk_priv *priv = dev_get_priv(clk->dev); 994 ulong ret = 0; 995 996 debug("%s %ld %ld\n", __func__, clk->id, rate); 997 switch (clk->id) { 998 case PLL_APLL: 999 case PLL_DPLL: 1000 ret = rockchip_pll_set_rate(&rk1808_pll_clks[clk->id - 1], 1001 priv->cru, clk->id - 1, rate); 1002 break; 1003 case PLL_PPLL: 1004 ret = rk1808_pclk_pmu_set_clk(priv, clk->id, rate, PCLK_PMU_HZ); 1005 ret = rockchip_pll_set_rate(&rk1808_pll_clks[PPLL], 1006 priv->cru, PPLL, rate); 1007 break; 1008 case PLL_CPLL: 1009 ret = rockchip_pll_set_rate(&rk1808_pll_clks[CPLL], 1010 priv->cru, CPLL, rate); 1011 if (ret == 0) 1012 priv->cpll_hz = rate; 1013 break; 1014 case PLL_GPLL: 1015 ret = rockchip_pll_set_rate(&rk1808_pll_clks[GPLL], 1016 priv->cru, GPLL, rate); 1017 if (ret == 0) 1018 priv->gpll_hz = rate; 1019 break; 1020 case PLL_NPLL: 1021 ret = rockchip_pll_set_rate(&rk1808_pll_clks[NPLL], 1022 priv->cru, NPLL, rate); 1023 if (ret == 0) 1024 priv->npll_hz = rate; 1025 break; 1026 case ARMCLK: 1027 if (priv->armclk_hz) 1028 rk1808_armclk_set_clk(priv, rate); 1029 priv->armclk_hz = rate; 1030 break; 1031 case HCLK_SDMMC: 1032 case HCLK_EMMC: 1033 case HCLK_SDIO: 1034 case SCLK_SDMMC: 1035 case SCLK_EMMC: 1036 case SCLK_SDIO: 1037 ret = rk1808_mmc_set_clk(priv, clk->id, rate); 1038 break; 1039 case SCLK_SFC: 1040 ret = rk1808_sfc_set_clk(priv, clk->id, rate); 1041 break; 1042 case SCLK_SARADC: 1043 ret = rk1808_saradc_set_clk(priv, rate); 1044 break; 1045 #ifndef CONFIG_SPL_BUILD 1046 case SCLK_PMU_I2C0: 1047 case SCLK_I2C1: 1048 case SCLK_I2C2: 1049 case SCLK_I2C3: 1050 case SCLK_I2C4: 1051 case SCLK_I2C5: 1052 ret = rk1808_i2c_set_clk(priv, clk->id, rate); 1053 break; 1054 case SCLK_PWM0: 1055 case SCLK_PWM1: 1056 case SCLK_PWM2: 1057 ret = rk1808_pwm_set_clk(priv, clk->id, rate); 1058 break; 1059 case SCLK_TSADC: 1060 ret = rk1808_tsadc_set_clk(priv, rate); 1061 break; 1062 case SCLK_SPI0: 1063 case SCLK_SPI1: 1064 case SCLK_SPI2: 1065 ret = rk1808_spi_set_clk(priv, clk->id, rate); 1066 break; 1067 case ACLK_VOPRAW: 1068 case DCLK_VOPRAW: 1069 case ACLK_VOPLITE: 1070 case DCLK_VOPLITE: 1071 ret = rk1808_vop_set_clk(priv, clk->id, rate); 1072 break; 1073 case SCLK_GMAC: 1074 case SCLK_GMAC_SRC: 1075 ret = rk1808_mac_set_clk(clk, rate); 1076 break; 1077 case SCLK_GMAC_RMII_SPEED: 1078 case SCLK_GMAC_RGMII_SPEED: 1079 ret = rk1808_mac_set_speed_clk(clk, clk->id, rate); 1080 break; 1081 case SCLK_CRYPTO: 1082 case SCLK_CRYPTO_APK: 1083 ret = rk1808_crypto_set_clk(priv, clk->id, rate); 1084 break; 1085 #endif 1086 case HSCLK_BUS_PRE: 1087 case MSCLK_BUS_PRE: 1088 case LSCLK_BUS_PRE: 1089 ret = rk1808_bus_set_clk(priv, clk->id, rate); 1090 break; 1091 case MSCLK_PERI: 1092 case LSCLK_PERI: 1093 ret = rk1808_peri_set_clk(priv, clk->id, rate); 1094 break; 1095 case SCLK_32K_IOE: 1096 return 0; 1097 default: 1098 return -ENOENT; 1099 } 1100 1101 return ret; 1102 } 1103 1104 #define ROCKCHIP_MMC_DELAY_SEL BIT(10) 1105 #define ROCKCHIP_MMC_DEGREE_MASK 0x3 1106 #define ROCKCHIP_MMC_DELAYNUM_OFFSET 2 1107 #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET) 1108 1109 #define PSECS_PER_SEC 1000000000000LL 1110 /* 1111 * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to 1112 * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg. 1113 */ 1114 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60 1115 1116 int rk1808_mmc_get_phase(struct clk *clk) 1117 { 1118 struct rk1808_clk_priv *priv = dev_get_priv(clk->dev); 1119 struct rk1808_cru *cru = priv->cru; 1120 u32 raw_value, delay_num; 1121 u16 degrees = 0; 1122 ulong rate; 1123 1124 rate = rk1808_clk_get_rate(clk); 1125 1126 if (rate < 0) 1127 return rate; 1128 1129 if (clk->id == SCLK_EMMC_SAMPLE) 1130 raw_value = readl(&cru->emmc_con[1]); 1131 else if (clk->id == SCLK_SDMMC_SAMPLE) 1132 raw_value = readl(&cru->sdmmc_con[1]); 1133 else 1134 raw_value = readl(&cru->sdio_con[1]); 1135 1136 raw_value >>= 1; 1137 degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90; 1138 1139 if (raw_value & ROCKCHIP_MMC_DELAY_SEL) { 1140 /* degrees/delaynum * 10000 */ 1141 unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) * 1142 36 * (rate / 1000000); 1143 1144 delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK); 1145 delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET; 1146 degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000); 1147 } 1148 1149 return degrees % 360; 1150 } 1151 1152 int rk1808_mmc_set_phase(struct clk *clk, u32 degrees) 1153 { 1154 struct rk1808_clk_priv *priv = dev_get_priv(clk->dev); 1155 struct rk1808_cru *cru = priv->cru; 1156 u8 nineties, remainder, delay_num; 1157 u32 raw_value, delay; 1158 ulong rate; 1159 1160 rate = rk1808_clk_get_rate(clk); 1161 1162 if (rate < 0) 1163 return rate; 1164 1165 nineties = degrees / 90; 1166 remainder = (degrees % 90); 1167 1168 /* 1169 * Convert to delay; do a little extra work to make sure we 1170 * don't overflow 32-bit / 64-bit numbers. 1171 */ 1172 delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */ 1173 delay *= remainder; 1174 delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 * 1175 (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10)); 1176 1177 delay_num = (u8)min_t(u32, delay, 255); 1178 1179 raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0; 1180 raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET; 1181 raw_value |= nineties; 1182 1183 raw_value <<= 1; 1184 if (clk->id == SCLK_EMMC_SAMPLE) 1185 writel(raw_value | 0xffff0000, &cru->emmc_con[1]); 1186 else if (clk->id == SCLK_SDMMC_SAMPLE) 1187 writel(raw_value | 0xffff0000, &cru->sdmmc_con[1]); 1188 else 1189 writel(raw_value | 0xffff0000, &cru->sdio_con[1]); 1190 1191 debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n", 1192 degrees, delay_num, raw_value, rk1808_mmc_get_phase(clk)); 1193 1194 return 0; 1195 } 1196 1197 static int rk1808_clk_get_phase(struct clk *clk) 1198 { 1199 int ret; 1200 1201 debug("%s %ld\n", __func__, clk->id); 1202 switch (clk->id) { 1203 case SCLK_EMMC_SAMPLE: 1204 case SCLK_SDMMC_SAMPLE: 1205 case SCLK_SDIO_SAMPLE: 1206 ret = rk1808_mmc_get_phase(clk); 1207 break; 1208 default: 1209 return -ENOENT; 1210 } 1211 1212 return ret; 1213 } 1214 1215 static int rk1808_clk_set_phase(struct clk *clk, int degrees) 1216 { 1217 int ret; 1218 1219 debug("%s %ld\n", __func__, clk->id); 1220 switch (clk->id) { 1221 case SCLK_EMMC_SAMPLE: 1222 case SCLK_SDMMC_SAMPLE: 1223 case SCLK_SDIO_SAMPLE: 1224 ret = rk1808_mmc_set_phase(clk, degrees); 1225 break; 1226 default: 1227 return -ENOENT; 1228 } 1229 1230 return ret; 1231 } 1232 1233 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) 1234 static int rk1808_gmac_set_parent(struct clk *clk, struct clk *parent) 1235 { 1236 struct rk1808_clk_priv *priv = dev_get_priv(clk->dev); 1237 struct rk1808_cru *cru = priv->cru; 1238 1239 if (parent->id == SCLK_GMAC_SRC) { 1240 debug("%s: switching GAMC to SCLK_GMAC_SRC\n", __func__); 1241 rk_clrsetreg(&cru->clksel_con[27], RMII_EXTCLK_SEL_MASK, 1242 RMII_EXTCLK_SEL_INT << RMII_EXTCLK_SEL_SHIFT); 1243 } else { 1244 debug("%s: switching GMAC to external clock\n", __func__); 1245 rk_clrsetreg(&cru->clksel_con[27], RMII_EXTCLK_SEL_MASK, 1246 RMII_EXTCLK_SEL_EXT << RMII_EXTCLK_SEL_SHIFT); 1247 } 1248 return 0; 1249 } 1250 1251 static int rk1808_clk_set_parent(struct clk *clk, struct clk *parent) 1252 { 1253 switch (clk->id) { 1254 case SCLK_GMAC: 1255 return rk1808_gmac_set_parent(clk, parent); 1256 case SCLK_32K_IOE: 1257 return 0; 1258 default: 1259 return -ENOENT; 1260 } 1261 } 1262 #endif 1263 1264 static struct clk_ops rk1808_clk_ops = { 1265 .get_rate = rk1808_clk_get_rate, 1266 .set_rate = rk1808_clk_set_rate, 1267 .get_phase = rk1808_clk_get_phase, 1268 .set_phase = rk1808_clk_set_phase, 1269 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) 1270 .set_parent = rk1808_clk_set_parent, 1271 #endif 1272 }; 1273 1274 static int rk1808_clk_probe(struct udevice *dev) 1275 { 1276 struct rk1808_clk_priv *priv = dev_get_priv(dev); 1277 int ret; 1278 #ifndef CONFIG_SPL_BUILD 1279 ulong crypto_rate, crypto_apk_rate; 1280 ulong emmc_rate, sdmmc_rate, sfc_rate; 1281 #endif 1282 1283 priv->sync_kernel = false; 1284 if (!priv->armclk_enter_hz) { 1285 priv->armclk_enter_hz = 1286 rockchip_pll_get_rate(&rk1808_pll_clks[APLL], 1287 priv->cru, APLL); 1288 priv->armclk_init_hz = priv->armclk_enter_hz; 1289 } 1290 if (rockchip_pll_get_rate(&rk1808_pll_clks[APLL], 1291 priv->cru, APLL) != APLL_HZ) { 1292 ret = rk1808_armclk_set_clk(priv, APLL_HZ); 1293 if (ret < 0) 1294 printf("%s failed to set armclk rate\n", __func__); 1295 priv->armclk_init_hz = APLL_HZ; 1296 } 1297 #ifdef CONFIG_SPL_BUILD 1298 /* 1299 * The eMMC clk is depended on gpll, and the eMMC is needed to 1300 * run 150MHz in HS200 mode. So set gpll to GPLL_HZ(594000000) 1301 * which can be divided near to 150MHz. 1302 */ 1303 ret = rockchip_pll_set_rate(&rk1808_pll_clks[GPLL], 1304 priv->cru, GPLL, GPLL_HZ); 1305 if (ret < 0) 1306 printf("%s failed to set gpll rate\n", __func__); 1307 #endif 1308 priv->cpll_hz = rockchip_pll_get_rate(&rk1808_pll_clks[CPLL], 1309 priv->cru, CPLL); 1310 priv->gpll_hz = rockchip_pll_get_rate(&rk1808_pll_clks[GPLL], 1311 priv->cru, GPLL); 1312 priv->npll_hz = rockchip_pll_get_rate(&rk1808_pll_clks[NPLL], 1313 priv->cru, NPLL); 1314 1315 #ifndef CONFIG_SPL_BUILD 1316 crypto_rate = rk1808_crypto_get_clk(priv, SCLK_CRYPTO); 1317 crypto_apk_rate = rk1808_crypto_get_clk(priv, SCLK_CRYPTO_APK); 1318 emmc_rate = rk1808_mmc_get_clk(priv, SCLK_EMMC); 1319 sdmmc_rate = rk1808_mmc_get_clk(priv, SCLK_SDMMC); 1320 sfc_rate = rk1808_sfc_get_clk(priv, SCLK_SFC); 1321 #endif 1322 1323 /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */ 1324 ret = clk_set_defaults(dev); 1325 if (ret) 1326 debug("%s clk_set_defaults failed %d\n", __func__, ret); 1327 else 1328 priv->sync_kernel = true; 1329 1330 #ifndef CONFIG_SPL_BUILD 1331 rk1808_crypto_set_clk(priv, SCLK_CRYPTO, crypto_rate); 1332 rk1808_crypto_set_clk(priv, SCLK_CRYPTO_APK, crypto_apk_rate); 1333 rk1808_mmc_set_clk(priv, SCLK_EMMC, emmc_rate); 1334 rk1808_mmc_set_clk(priv, SCLK_SDMMC, sdmmc_rate); 1335 rk1808_sfc_set_clk(priv, SCLK_SFC, sfc_rate); 1336 #endif 1337 1338 return 0; 1339 } 1340 1341 static int rk1808_clk_ofdata_to_platdata(struct udevice *dev) 1342 { 1343 struct rk1808_clk_priv *priv = dev_get_priv(dev); 1344 1345 priv->cru = dev_read_addr_ptr(dev); 1346 1347 return 0; 1348 } 1349 1350 static int rk1808_clk_bind(struct udevice *dev) 1351 { 1352 int ret; 1353 struct udevice *sys_child, *sf_child; 1354 struct sysreset_reg *priv; 1355 struct softreset_reg *sf_priv; 1356 1357 /* The reset driver does not have a device node, so bind it here */ 1358 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset", 1359 &sys_child); 1360 if (ret) { 1361 debug("Warning: No sysreset driver: ret=%d\n", ret); 1362 } else { 1363 priv = malloc(sizeof(struct sysreset_reg)); 1364 priv->glb_srst_fst_value = offsetof(struct rk1808_cru, 1365 glb_srst_fst); 1366 priv->glb_srst_snd_value = offsetof(struct rk1808_cru, 1367 glb_srst_snd); 1368 sys_child->priv = priv; 1369 } 1370 1371 ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset", 1372 dev_ofnode(dev), &sf_child); 1373 if (ret) { 1374 debug("Warning: No rockchip reset driver: ret=%d\n", ret); 1375 } else { 1376 sf_priv = malloc(sizeof(struct softreset_reg)); 1377 sf_priv->sf_reset_offset = offsetof(struct rk1808_cru, 1378 softrst_con[0]); 1379 sf_priv->sf_reset_num = 16; 1380 sf_child->priv = sf_priv; 1381 } 1382 1383 return 0; 1384 } 1385 1386 static const struct udevice_id rk1808_clk_ids[] = { 1387 { .compatible = "rockchip,rk1808-cru" }, 1388 { } 1389 }; 1390 1391 U_BOOT_DRIVER(rockchip_rk1808_cru) = { 1392 .name = "rockchip_rk1808_cru", 1393 .id = UCLASS_CLK, 1394 .of_match = rk1808_clk_ids, 1395 .priv_auto_alloc_size = sizeof(struct rk1808_clk_priv), 1396 .ofdata_to_platdata = rk1808_clk_ofdata_to_platdata, 1397 .ops = &rk1808_clk_ops, 1398 .bind = rk1808_clk_bind, 1399 .probe = rk1808_clk_probe, 1400 }; 1401 1402 #ifndef CONFIG_SPL_BUILD 1403 /** 1404 * soc_clk_dump() - Print clock frequencies 1405 * Returns zero on success 1406 * 1407 * Implementation for the clk dump command. 1408 */ 1409 int soc_clk_dump(void) 1410 { 1411 struct udevice *cru_dev; 1412 struct rk1808_clk_priv *priv; 1413 const struct rk1808_clk_info *clk_dump; 1414 struct clk clk; 1415 unsigned long clk_count = ARRAY_SIZE(clks_dump); 1416 unsigned long rate; 1417 int i, ret; 1418 1419 ret = uclass_get_device_by_driver(UCLASS_CLK, 1420 DM_GET_DRIVER(rockchip_rk1808_cru), 1421 &cru_dev); 1422 if (ret) { 1423 printf("%s failed to get cru device\n", __func__); 1424 return ret; 1425 } 1426 1427 priv = dev_get_priv(cru_dev); 1428 printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n", 1429 priv->sync_kernel ? "sync kernel" : "uboot", 1430 priv->armclk_enter_hz / 1000, 1431 priv->armclk_init_hz / 1000, 1432 priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0, 1433 priv->set_armclk_rate ? " KHz" : "N/A"); 1434 1435 for (i = 0; i < clk_count; i++) { 1436 clk_dump = &clks_dump[i]; 1437 if (clk_dump->name) { 1438 clk.id = clk_dump->id; 1439 if (clk_dump->is_cru) 1440 ret = clk_request(cru_dev, &clk); 1441 if (ret < 0) 1442 return ret; 1443 1444 rate = clk_get_rate(&clk); 1445 clk_free(&clk); 1446 if (i == 0) { 1447 if (rate < 0) 1448 printf(" %s %s\n", clk_dump->name, 1449 "unknown"); 1450 else 1451 printf(" %s %lu KHz\n", clk_dump->name, 1452 rate / 1000); 1453 } else { 1454 if (rate < 0) 1455 printf(" %s %s\n", clk_dump->name, 1456 "unknown"); 1457 else 1458 printf(" %s %lu KHz\n", clk_dump->name, 1459 rate / 1000); 1460 } 1461 } 1462 } 1463 1464 return 0; 1465 } 1466 #endif 1467