1 /* 2 * Copyright (C) 2010 Samsung Electronics 3 * Minkyu Kang <mk7.kang@samsung.com> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 #include <asm/io.h> 10 #include <asm/arch/clock.h> 11 #include <asm/arch/clk.h> 12 #include <asm/arch/periph.h> 13 14 #define PLL_DIV_1024 1024 15 #define PLL_DIV_65535 65535 16 #define PLL_DIV_65536 65536 17 /* * 18 * This structure is to store the src bit, div bit and prediv bit 19 * positions of the peripheral clocks of the src and div registers 20 */ 21 struct clk_bit_info { 22 enum periph_id id; 23 int32_t src_mask; 24 int32_t div_mask; 25 int32_t prediv_mask; 26 int8_t src_bit; 27 int8_t div_bit; 28 int8_t prediv_bit; 29 }; 30 31 static struct clk_bit_info exynos5_bit_info[] = { 32 /* periph id s_mask d_mask p_mask s_bit d_bit p_bit */ 33 {PERIPH_ID_UART0, 0xf, 0xf, -1, 0, 0, -1}, 34 {PERIPH_ID_UART1, 0xf, 0xf, -1, 4, 4, -1}, 35 {PERIPH_ID_UART2, 0xf, 0xf, -1, 8, 8, -1}, 36 {PERIPH_ID_UART3, 0xf, 0xf, -1, 12, 12, -1}, 37 {PERIPH_ID_I2C0, -1, 0x7, 0x7, -1, 24, 0}, 38 {PERIPH_ID_I2C1, -1, 0x7, 0x7, -1, 24, 0}, 39 {PERIPH_ID_I2C2, -1, 0x7, 0x7, -1, 24, 0}, 40 {PERIPH_ID_I2C3, -1, 0x7, 0x7, -1, 24, 0}, 41 {PERIPH_ID_I2C4, -1, 0x7, 0x7, -1, 24, 0}, 42 {PERIPH_ID_I2C5, -1, 0x7, 0x7, -1, 24, 0}, 43 {PERIPH_ID_I2C6, -1, 0x7, 0x7, -1, 24, 0}, 44 {PERIPH_ID_I2C7, -1, 0x7, 0x7, -1, 24, 0}, 45 {PERIPH_ID_SPI0, 0xf, 0xf, 0xff, 16, 0, 8}, 46 {PERIPH_ID_SPI1, 0xf, 0xf, 0xff, 20, 16, 24}, 47 {PERIPH_ID_SPI2, 0xf, 0xf, 0xff, 24, 0, 8}, 48 {PERIPH_ID_SDMMC0, 0xf, 0xf, 0xff, 0, 0, 8}, 49 {PERIPH_ID_SDMMC1, 0xf, 0xf, 0xff, 4, 16, 24}, 50 {PERIPH_ID_SDMMC2, 0xf, 0xf, 0xff, 8, 0, 8}, 51 {PERIPH_ID_SDMMC3, 0xf, 0xf, 0xff, 12, 16, 24}, 52 {PERIPH_ID_I2S0, 0xf, 0xf, 0xff, 0, 0, 4}, 53 {PERIPH_ID_I2S1, 0xf, 0xf, 0xff, 4, 12, 16}, 54 {PERIPH_ID_SPI3, 0xf, 0xf, 0xff, 0, 0, 4}, 55 {PERIPH_ID_SPI4, 0xf, 0xf, 0xff, 4, 12, 16}, 56 {PERIPH_ID_SDMMC4, 0xf, 0xf, 0xff, 16, 0, 8}, 57 {PERIPH_ID_PWM0, 0xf, 0xf, -1, 24, 0, -1}, 58 {PERIPH_ID_PWM1, 0xf, 0xf, -1, 24, 0, -1}, 59 {PERIPH_ID_PWM2, 0xf, 0xf, -1, 24, 0, -1}, 60 {PERIPH_ID_PWM3, 0xf, 0xf, -1, 24, 0, -1}, 61 {PERIPH_ID_PWM4, 0xf, 0xf, -1, 24, 0, -1}, 62 63 {PERIPH_ID_NONE, -1, -1, -1, -1, -1, -1}, 64 }; 65 66 static struct clk_bit_info exynos542x_bit_info[] = { 67 /* periph id s_mask d_mask p_mask s_bit d_bit p_bit */ 68 {PERIPH_ID_UART0, 0xf, 0xf, -1, 4, 8, -1}, 69 {PERIPH_ID_UART1, 0xf, 0xf, -1, 8, 12, -1}, 70 {PERIPH_ID_UART2, 0xf, 0xf, -1, 12, 16, -1}, 71 {PERIPH_ID_UART3, 0xf, 0xf, -1, 16, 20, -1}, 72 {PERIPH_ID_I2C0, -1, 0x3f, -1, -1, 8, -1}, 73 {PERIPH_ID_I2C1, -1, 0x3f, -1, -1, 8, -1}, 74 {PERIPH_ID_I2C2, -1, 0x3f, -1, -1, 8, -1}, 75 {PERIPH_ID_I2C3, -1, 0x3f, -1, -1, 8, -1}, 76 {PERIPH_ID_I2C4, -1, 0x3f, -1, -1, 8, -1}, 77 {PERIPH_ID_I2C5, -1, 0x3f, -1, -1, 8, -1}, 78 {PERIPH_ID_I2C6, -1, 0x3f, -1, -1, 8, -1}, 79 {PERIPH_ID_I2C7, -1, 0x3f, -1, -1, 8, -1}, 80 {PERIPH_ID_SPI0, 0xf, 0xf, 0xff, 20, 20, 8}, 81 {PERIPH_ID_SPI1, 0xf, 0xf, 0xff, 24, 24, 16}, 82 {PERIPH_ID_SPI2, 0xf, 0xf, 0xff, 28, 28, 24}, 83 {PERIPH_ID_SDMMC0, 0x7, 0x3ff, -1, 8, 0, -1}, 84 {PERIPH_ID_SDMMC1, 0x7, 0x3ff, -1, 12, 10, -1}, 85 {PERIPH_ID_SDMMC2, 0x7, 0x3ff, -1, 16, 20, -1}, 86 {PERIPH_ID_I2C8, -1, 0x3f, -1, -1, 8, -1}, 87 {PERIPH_ID_I2C9, -1, 0x3f, -1, -1, 8, -1}, 88 {PERIPH_ID_I2S0, 0xf, 0xf, 0xff, 0, 0, 4}, 89 {PERIPH_ID_I2S1, 0xf, 0xf, 0xff, 4, 12, 16}, 90 {PERIPH_ID_SPI3, 0xf, 0xf, 0xff, 12, 16, 0}, 91 {PERIPH_ID_SPI4, 0xf, 0xf, 0xff, 16, 20, 8}, 92 {PERIPH_ID_PWM0, 0xf, 0xf, -1, 24, 28, -1}, 93 {PERIPH_ID_PWM1, 0xf, 0xf, -1, 24, 28, -1}, 94 {PERIPH_ID_PWM2, 0xf, 0xf, -1, 24, 28, -1}, 95 {PERIPH_ID_PWM3, 0xf, 0xf, -1, 24, 28, -1}, 96 {PERIPH_ID_PWM4, 0xf, 0xf, -1, 24, 28, -1}, 97 {PERIPH_ID_I2C10, -1, 0x3f, -1, -1, 8, -1}, 98 99 {PERIPH_ID_NONE, -1, -1, -1, -1, -1, -1}, 100 }; 101 102 /* Epll Clock division values to achive different frequency output */ 103 static struct set_epll_con_val exynos5_epll_div[] = { 104 { 192000000, 0, 48, 3, 1, 0 }, 105 { 180000000, 0, 45, 3, 1, 0 }, 106 { 73728000, 1, 73, 3, 3, 47710 }, 107 { 67737600, 1, 90, 4, 3, 20762 }, 108 { 49152000, 0, 49, 3, 3, 9961 }, 109 { 45158400, 0, 45, 3, 3, 10381 }, 110 { 180633600, 0, 45, 3, 1, 10381 } 111 }; 112 113 /* exynos: return pll clock frequency */ 114 static int exynos_get_pll_clk(int pllreg, unsigned int r, unsigned int k) 115 { 116 unsigned long m, p, s = 0, mask, fout; 117 unsigned int div; 118 unsigned int freq; 119 /* 120 * APLL_CON: MIDV [25:16] 121 * MPLL_CON: MIDV [25:16] 122 * EPLL_CON: MIDV [24:16] 123 * VPLL_CON: MIDV [24:16] 124 * BPLL_CON: MIDV [25:16]: Exynos5 125 */ 126 if (pllreg == APLL || pllreg == MPLL || pllreg == BPLL || 127 pllreg == SPLL) 128 mask = 0x3ff; 129 else 130 mask = 0x1ff; 131 132 m = (r >> 16) & mask; 133 134 /* PDIV [13:8] */ 135 p = (r >> 8) & 0x3f; 136 /* SDIV [2:0] */ 137 s = r & 0x7; 138 139 freq = CONFIG_SYS_CLK_FREQ; 140 141 if (pllreg == EPLL || pllreg == RPLL) { 142 k = k & 0xffff; 143 /* FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV) */ 144 fout = (m + k / PLL_DIV_65536) * (freq / (p * (1 << s))); 145 } else if (pllreg == VPLL) { 146 k = k & 0xfff; 147 148 /* 149 * Exynos4210 150 * FOUT = (MDIV + K / 1024) * FIN / (PDIV * 2^SDIV) 151 * 152 * Exynos4412 153 * FOUT = (MDIV + K / 65535) * FIN / (PDIV * 2^SDIV) 154 * 155 * Exynos5250 156 * FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV) 157 */ 158 if (proid_is_exynos4210()) 159 div = PLL_DIV_1024; 160 else if (proid_is_exynos4412()) 161 div = PLL_DIV_65535; 162 else if (proid_is_exynos5250() || proid_is_exynos5420() 163 || proid_is_exynos5800()) 164 div = PLL_DIV_65536; 165 else 166 return 0; 167 168 fout = (m + k / div) * (freq / (p * (1 << s))); 169 } else { 170 /* 171 * Exynos4412 / Exynos5250 172 * FOUT = MDIV * FIN / (PDIV * 2^SDIV) 173 * 174 * Exynos4210 175 * FOUT = MDIV * FIN / (PDIV * 2^(SDIV-1)) 176 */ 177 if (proid_is_exynos4210()) 178 fout = m * (freq / (p * (1 << (s - 1)))); 179 else 180 fout = m * (freq / (p * (1 << s))); 181 } 182 return fout; 183 } 184 185 /* exynos4: return pll clock frequency */ 186 static unsigned long exynos4_get_pll_clk(int pllreg) 187 { 188 struct exynos4_clock *clk = 189 (struct exynos4_clock *)samsung_get_base_clock(); 190 unsigned long r, k = 0; 191 192 switch (pllreg) { 193 case APLL: 194 r = readl(&clk->apll_con0); 195 break; 196 case MPLL: 197 r = readl(&clk->mpll_con0); 198 break; 199 case EPLL: 200 r = readl(&clk->epll_con0); 201 k = readl(&clk->epll_con1); 202 break; 203 case VPLL: 204 r = readl(&clk->vpll_con0); 205 k = readl(&clk->vpll_con1); 206 break; 207 default: 208 printf("Unsupported PLL (%d)\n", pllreg); 209 return 0; 210 } 211 212 return exynos_get_pll_clk(pllreg, r, k); 213 } 214 215 /* exynos4x12: return pll clock frequency */ 216 static unsigned long exynos4x12_get_pll_clk(int pllreg) 217 { 218 struct exynos4x12_clock *clk = 219 (struct exynos4x12_clock *)samsung_get_base_clock(); 220 unsigned long r, k = 0; 221 222 switch (pllreg) { 223 case APLL: 224 r = readl(&clk->apll_con0); 225 break; 226 case MPLL: 227 r = readl(&clk->mpll_con0); 228 break; 229 case EPLL: 230 r = readl(&clk->epll_con0); 231 k = readl(&clk->epll_con1); 232 break; 233 case VPLL: 234 r = readl(&clk->vpll_con0); 235 k = readl(&clk->vpll_con1); 236 break; 237 default: 238 printf("Unsupported PLL (%d)\n", pllreg); 239 return 0; 240 } 241 242 return exynos_get_pll_clk(pllreg, r, k); 243 } 244 245 /* exynos5: return pll clock frequency */ 246 static unsigned long exynos5_get_pll_clk(int pllreg) 247 { 248 struct exynos5_clock *clk = 249 (struct exynos5_clock *)samsung_get_base_clock(); 250 unsigned long r, k = 0, fout; 251 unsigned int pll_div2_sel, fout_sel; 252 253 switch (pllreg) { 254 case APLL: 255 r = readl(&clk->apll_con0); 256 break; 257 case MPLL: 258 r = readl(&clk->mpll_con0); 259 break; 260 case EPLL: 261 r = readl(&clk->epll_con0); 262 k = readl(&clk->epll_con1); 263 break; 264 case VPLL: 265 r = readl(&clk->vpll_con0); 266 k = readl(&clk->vpll_con1); 267 break; 268 case BPLL: 269 r = readl(&clk->bpll_con0); 270 break; 271 default: 272 printf("Unsupported PLL (%d)\n", pllreg); 273 return 0; 274 } 275 276 fout = exynos_get_pll_clk(pllreg, r, k); 277 278 /* According to the user manual, in EVT1 MPLL and BPLL always gives 279 * 1.6GHz clock, so divide by 2 to get 800MHz MPLL clock.*/ 280 if (pllreg == MPLL || pllreg == BPLL) { 281 pll_div2_sel = readl(&clk->pll_div2_sel); 282 283 switch (pllreg) { 284 case MPLL: 285 fout_sel = (pll_div2_sel >> MPLL_FOUT_SEL_SHIFT) 286 & MPLL_FOUT_SEL_MASK; 287 break; 288 case BPLL: 289 fout_sel = (pll_div2_sel >> BPLL_FOUT_SEL_SHIFT) 290 & BPLL_FOUT_SEL_MASK; 291 break; 292 default: 293 fout_sel = -1; 294 break; 295 } 296 297 if (fout_sel == 0) 298 fout /= 2; 299 } 300 301 return fout; 302 } 303 304 /* exynos542x: return pll clock frequency */ 305 static unsigned long exynos542x_get_pll_clk(int pllreg) 306 { 307 struct exynos5420_clock *clk = 308 (struct exynos5420_clock *)samsung_get_base_clock(); 309 unsigned long r, k = 0; 310 311 switch (pllreg) { 312 case APLL: 313 r = readl(&clk->apll_con0); 314 break; 315 case MPLL: 316 r = readl(&clk->mpll_con0); 317 break; 318 case EPLL: 319 r = readl(&clk->epll_con0); 320 k = readl(&clk->epll_con1); 321 break; 322 case VPLL: 323 r = readl(&clk->vpll_con0); 324 k = readl(&clk->vpll_con1); 325 break; 326 case BPLL: 327 r = readl(&clk->bpll_con0); 328 break; 329 case RPLL: 330 r = readl(&clk->rpll_con0); 331 k = readl(&clk->rpll_con1); 332 break; 333 case SPLL: 334 r = readl(&clk->spll_con0); 335 break; 336 default: 337 printf("Unsupported PLL (%d)\n", pllreg); 338 return 0; 339 } 340 341 return exynos_get_pll_clk(pllreg, r, k); 342 } 343 344 static struct clk_bit_info *get_clk_bit_info(int peripheral) 345 { 346 int i; 347 struct clk_bit_info *info; 348 349 if (proid_is_exynos5420() || proid_is_exynos5800()) 350 info = exynos542x_bit_info; 351 else 352 info = exynos5_bit_info; 353 354 for (i = 0; info[i].id != PERIPH_ID_NONE; i++) { 355 if (info[i].id == peripheral) 356 break; 357 } 358 359 if (info[i].id == PERIPH_ID_NONE) 360 debug("ERROR: Peripheral ID %d not found\n", peripheral); 361 362 return &info[i]; 363 } 364 365 static unsigned long exynos5_get_periph_rate(int peripheral) 366 { 367 struct clk_bit_info *bit_info = get_clk_bit_info(peripheral); 368 unsigned long sclk = 0; 369 unsigned int src = 0, div = 0, sub_div = 0; 370 struct exynos5_clock *clk = 371 (struct exynos5_clock *)samsung_get_base_clock(); 372 373 switch (peripheral) { 374 case PERIPH_ID_UART0: 375 case PERIPH_ID_UART1: 376 case PERIPH_ID_UART2: 377 case PERIPH_ID_UART3: 378 src = readl(&clk->src_peric0); 379 div = readl(&clk->div_peric0); 380 break; 381 case PERIPH_ID_PWM0: 382 case PERIPH_ID_PWM1: 383 case PERIPH_ID_PWM2: 384 case PERIPH_ID_PWM3: 385 case PERIPH_ID_PWM4: 386 src = readl(&clk->src_peric0); 387 div = readl(&clk->div_peric3); 388 break; 389 case PERIPH_ID_I2S0: 390 src = readl(&clk->src_mau); 391 div = sub_div = readl(&clk->div_mau); 392 case PERIPH_ID_SPI0: 393 case PERIPH_ID_SPI1: 394 src = readl(&clk->src_peric1); 395 div = sub_div = readl(&clk->div_peric1); 396 break; 397 case PERIPH_ID_SPI2: 398 src = readl(&clk->src_peric1); 399 div = sub_div = readl(&clk->div_peric2); 400 break; 401 case PERIPH_ID_SPI3: 402 case PERIPH_ID_SPI4: 403 src = readl(&clk->sclk_src_isp); 404 div = sub_div = readl(&clk->sclk_div_isp); 405 break; 406 case PERIPH_ID_SDMMC0: 407 case PERIPH_ID_SDMMC1: 408 src = readl(&clk->src_fsys); 409 div = sub_div = readl(&clk->div_fsys1); 410 break; 411 case PERIPH_ID_SDMMC2: 412 case PERIPH_ID_SDMMC3: 413 src = readl(&clk->src_fsys); 414 div = sub_div = readl(&clk->div_fsys2); 415 break; 416 case PERIPH_ID_I2C0: 417 case PERIPH_ID_I2C1: 418 case PERIPH_ID_I2C2: 419 case PERIPH_ID_I2C3: 420 case PERIPH_ID_I2C4: 421 case PERIPH_ID_I2C5: 422 case PERIPH_ID_I2C6: 423 case PERIPH_ID_I2C7: 424 src = EXYNOS_SRC_MPLL; 425 div = readl(&clk->div_top1); 426 sub_div = readl(&clk->div_top0); 427 break; 428 default: 429 debug("%s: invalid peripheral %d", __func__, peripheral); 430 return -1; 431 }; 432 433 if (bit_info->src_bit >= 0) 434 src = (src >> bit_info->src_bit) & bit_info->src_mask; 435 436 switch (src) { 437 case EXYNOS_SRC_MPLL: 438 sclk = exynos5_get_pll_clk(MPLL); 439 break; 440 case EXYNOS_SRC_EPLL: 441 sclk = exynos5_get_pll_clk(EPLL); 442 break; 443 case EXYNOS_SRC_VPLL: 444 sclk = exynos5_get_pll_clk(VPLL); 445 break; 446 default: 447 debug("%s: EXYNOS_SRC %d not supported\n", __func__, src); 448 return 0; 449 } 450 451 /* Clock divider ratio for this peripheral */ 452 if (bit_info->div_bit >= 0) 453 div = (div >> bit_info->div_bit) & bit_info->div_mask; 454 455 /* Clock pre-divider ratio for this peripheral */ 456 if (bit_info->prediv_bit >= 0) 457 sub_div = (sub_div >> bit_info->prediv_bit) 458 & bit_info->prediv_mask; 459 460 /* Calculate and return required clock rate */ 461 return (sclk / (div + 1)) / (sub_div + 1); 462 } 463 464 static unsigned long exynos542x_get_periph_rate(int peripheral) 465 { 466 struct clk_bit_info *bit_info = get_clk_bit_info(peripheral); 467 unsigned long sclk = 0; 468 unsigned int src = 0, div = 0, sub_div = 0; 469 struct exynos5420_clock *clk = 470 (struct exynos5420_clock *)samsung_get_base_clock(); 471 472 switch (peripheral) { 473 case PERIPH_ID_UART0: 474 case PERIPH_ID_UART1: 475 case PERIPH_ID_UART2: 476 case PERIPH_ID_UART3: 477 case PERIPH_ID_PWM0: 478 case PERIPH_ID_PWM1: 479 case PERIPH_ID_PWM2: 480 case PERIPH_ID_PWM3: 481 case PERIPH_ID_PWM4: 482 src = readl(&clk->src_peric0); 483 div = readl(&clk->div_peric0); 484 break; 485 case PERIPH_ID_SPI0: 486 case PERIPH_ID_SPI1: 487 case PERIPH_ID_SPI2: 488 src = readl(&clk->src_peric1); 489 div = readl(&clk->div_peric1); 490 sub_div = readl(&clk->div_peric4); 491 break; 492 case PERIPH_ID_SPI3: 493 case PERIPH_ID_SPI4: 494 src = readl(&clk->src_isp); 495 div = readl(&clk->div_isp1); 496 sub_div = readl(&clk->div_isp1); 497 break; 498 case PERIPH_ID_SDMMC0: 499 case PERIPH_ID_SDMMC1: 500 case PERIPH_ID_SDMMC2: 501 case PERIPH_ID_SDMMC3: 502 src = readl(&clk->src_fsys); 503 div = readl(&clk->div_fsys1); 504 break; 505 case PERIPH_ID_I2C0: 506 case PERIPH_ID_I2C1: 507 case PERIPH_ID_I2C2: 508 case PERIPH_ID_I2C3: 509 case PERIPH_ID_I2C4: 510 case PERIPH_ID_I2C5: 511 case PERIPH_ID_I2C6: 512 case PERIPH_ID_I2C7: 513 case PERIPH_ID_I2C8: 514 case PERIPH_ID_I2C9: 515 case PERIPH_ID_I2C10: 516 src = EXYNOS542X_SRC_MPLL; 517 div = readl(&clk->div_top1); 518 break; 519 default: 520 debug("%s: invalid peripheral %d", __func__, peripheral); 521 return -1; 522 }; 523 524 if (bit_info->src_bit >= 0) 525 src = (src >> bit_info->src_bit) & bit_info->src_mask; 526 527 switch (src) { 528 case EXYNOS542X_SRC_MPLL: 529 sclk = exynos542x_get_pll_clk(MPLL); 530 break; 531 case EXYNOS542X_SRC_SPLL: 532 sclk = exynos542x_get_pll_clk(SPLL); 533 break; 534 case EXYNOS542X_SRC_EPLL: 535 sclk = exynos542x_get_pll_clk(EPLL); 536 break; 537 case EXYNOS542X_SRC_RPLL: 538 sclk = exynos542x_get_pll_clk(RPLL); 539 break; 540 default: 541 debug("%s: EXYNOS542X_SRC %d not supported", __func__, src); 542 return 0; 543 } 544 545 /* Clock divider ratio for this peripheral */ 546 if (bit_info->div_bit >= 0) 547 div = (div >> bit_info->div_bit) & bit_info->div_mask; 548 549 /* Clock pre-divider ratio for this peripheral */ 550 if (bit_info->prediv_bit >= 0) 551 sub_div = (sub_div >> bit_info->prediv_bit) 552 & bit_info->prediv_mask; 553 554 /* Calculate and return required clock rate */ 555 return (sclk / (div + 1)) / (sub_div + 1); 556 } 557 558 unsigned long clock_get_periph_rate(int peripheral) 559 { 560 if (cpu_is_exynos5()) { 561 if (proid_is_exynos5420() || proid_is_exynos5800()) 562 return exynos542x_get_periph_rate(peripheral); 563 return exynos5_get_periph_rate(peripheral); 564 } else { 565 return 0; 566 } 567 } 568 569 /* exynos4: return ARM clock frequency */ 570 static unsigned long exynos4_get_arm_clk(void) 571 { 572 struct exynos4_clock *clk = 573 (struct exynos4_clock *)samsung_get_base_clock(); 574 unsigned long div; 575 unsigned long armclk; 576 unsigned int core_ratio; 577 unsigned int core2_ratio; 578 579 div = readl(&clk->div_cpu0); 580 581 /* CORE_RATIO: [2:0], CORE2_RATIO: [30:28] */ 582 core_ratio = (div >> 0) & 0x7; 583 core2_ratio = (div >> 28) & 0x7; 584 585 armclk = get_pll_clk(APLL) / (core_ratio + 1); 586 armclk /= (core2_ratio + 1); 587 588 return armclk; 589 } 590 591 /* exynos4x12: return ARM clock frequency */ 592 static unsigned long exynos4x12_get_arm_clk(void) 593 { 594 struct exynos4x12_clock *clk = 595 (struct exynos4x12_clock *)samsung_get_base_clock(); 596 unsigned long div; 597 unsigned long armclk; 598 unsigned int core_ratio; 599 unsigned int core2_ratio; 600 601 div = readl(&clk->div_cpu0); 602 603 /* CORE_RATIO: [2:0], CORE2_RATIO: [30:28] */ 604 core_ratio = (div >> 0) & 0x7; 605 core2_ratio = (div >> 28) & 0x7; 606 607 armclk = get_pll_clk(APLL) / (core_ratio + 1); 608 armclk /= (core2_ratio + 1); 609 610 return armclk; 611 } 612 613 /* exynos5: return ARM clock frequency */ 614 static unsigned long exynos5_get_arm_clk(void) 615 { 616 struct exynos5_clock *clk = 617 (struct exynos5_clock *)samsung_get_base_clock(); 618 unsigned long div; 619 unsigned long armclk; 620 unsigned int arm_ratio; 621 unsigned int arm2_ratio; 622 623 div = readl(&clk->div_cpu0); 624 625 /* ARM_RATIO: [2:0], ARM2_RATIO: [30:28] */ 626 arm_ratio = (div >> 0) & 0x7; 627 arm2_ratio = (div >> 28) & 0x7; 628 629 armclk = get_pll_clk(APLL) / (arm_ratio + 1); 630 armclk /= (arm2_ratio + 1); 631 632 return armclk; 633 } 634 635 /* exynos4: return pwm clock frequency */ 636 static unsigned long exynos4_get_pwm_clk(void) 637 { 638 struct exynos4_clock *clk = 639 (struct exynos4_clock *)samsung_get_base_clock(); 640 unsigned long pclk, sclk; 641 unsigned int sel; 642 unsigned int ratio; 643 644 if (s5p_get_cpu_rev() == 0) { 645 /* 646 * CLK_SRC_PERIL0 647 * PWM_SEL [27:24] 648 */ 649 sel = readl(&clk->src_peril0); 650 sel = (sel >> 24) & 0xf; 651 652 if (sel == 0x6) 653 sclk = get_pll_clk(MPLL); 654 else if (sel == 0x7) 655 sclk = get_pll_clk(EPLL); 656 else if (sel == 0x8) 657 sclk = get_pll_clk(VPLL); 658 else 659 return 0; 660 661 /* 662 * CLK_DIV_PERIL3 663 * PWM_RATIO [3:0] 664 */ 665 ratio = readl(&clk->div_peril3); 666 ratio = ratio & 0xf; 667 } else if (s5p_get_cpu_rev() == 1) { 668 sclk = get_pll_clk(MPLL); 669 ratio = 8; 670 } else 671 return 0; 672 673 pclk = sclk / (ratio + 1); 674 675 return pclk; 676 } 677 678 /* exynos4x12: return pwm clock frequency */ 679 static unsigned long exynos4x12_get_pwm_clk(void) 680 { 681 unsigned long pclk, sclk; 682 unsigned int ratio; 683 684 sclk = get_pll_clk(MPLL); 685 ratio = 8; 686 687 pclk = sclk / (ratio + 1); 688 689 return pclk; 690 } 691 692 /* exynos4: return uart clock frequency */ 693 static unsigned long exynos4_get_uart_clk(int dev_index) 694 { 695 struct exynos4_clock *clk = 696 (struct exynos4_clock *)samsung_get_base_clock(); 697 unsigned long uclk, sclk; 698 unsigned int sel; 699 unsigned int ratio; 700 701 /* 702 * CLK_SRC_PERIL0 703 * UART0_SEL [3:0] 704 * UART1_SEL [7:4] 705 * UART2_SEL [8:11] 706 * UART3_SEL [12:15] 707 * UART4_SEL [16:19] 708 * UART5_SEL [23:20] 709 */ 710 sel = readl(&clk->src_peril0); 711 sel = (sel >> (dev_index << 2)) & 0xf; 712 713 if (sel == 0x6) 714 sclk = get_pll_clk(MPLL); 715 else if (sel == 0x7) 716 sclk = get_pll_clk(EPLL); 717 else if (sel == 0x8) 718 sclk = get_pll_clk(VPLL); 719 else 720 return 0; 721 722 /* 723 * CLK_DIV_PERIL0 724 * UART0_RATIO [3:0] 725 * UART1_RATIO [7:4] 726 * UART2_RATIO [8:11] 727 * UART3_RATIO [12:15] 728 * UART4_RATIO [16:19] 729 * UART5_RATIO [23:20] 730 */ 731 ratio = readl(&clk->div_peril0); 732 ratio = (ratio >> (dev_index << 2)) & 0xf; 733 734 uclk = sclk / (ratio + 1); 735 736 return uclk; 737 } 738 739 /* exynos4x12: return uart clock frequency */ 740 static unsigned long exynos4x12_get_uart_clk(int dev_index) 741 { 742 struct exynos4x12_clock *clk = 743 (struct exynos4x12_clock *)samsung_get_base_clock(); 744 unsigned long uclk, sclk; 745 unsigned int sel; 746 unsigned int ratio; 747 748 /* 749 * CLK_SRC_PERIL0 750 * UART0_SEL [3:0] 751 * UART1_SEL [7:4] 752 * UART2_SEL [8:11] 753 * UART3_SEL [12:15] 754 * UART4_SEL [16:19] 755 */ 756 sel = readl(&clk->src_peril0); 757 sel = (sel >> (dev_index << 2)) & 0xf; 758 759 if (sel == 0x6) 760 sclk = get_pll_clk(MPLL); 761 else if (sel == 0x7) 762 sclk = get_pll_clk(EPLL); 763 else if (sel == 0x8) 764 sclk = get_pll_clk(VPLL); 765 else 766 return 0; 767 768 /* 769 * CLK_DIV_PERIL0 770 * UART0_RATIO [3:0] 771 * UART1_RATIO [7:4] 772 * UART2_RATIO [8:11] 773 * UART3_RATIO [12:15] 774 * UART4_RATIO [16:19] 775 */ 776 ratio = readl(&clk->div_peril0); 777 ratio = (ratio >> (dev_index << 2)) & 0xf; 778 779 uclk = sclk / (ratio + 1); 780 781 return uclk; 782 } 783 784 static unsigned long exynos4_get_mmc_clk(int dev_index) 785 { 786 struct exynos4_clock *clk = 787 (struct exynos4_clock *)samsung_get_base_clock(); 788 unsigned long uclk, sclk; 789 unsigned int sel, ratio, pre_ratio; 790 int shift = 0; 791 792 sel = readl(&clk->src_fsys); 793 sel = (sel >> (dev_index << 2)) & 0xf; 794 795 if (sel == 0x6) 796 sclk = get_pll_clk(MPLL); 797 else if (sel == 0x7) 798 sclk = get_pll_clk(EPLL); 799 else if (sel == 0x8) 800 sclk = get_pll_clk(VPLL); 801 else 802 return 0; 803 804 switch (dev_index) { 805 case 0: 806 case 1: 807 ratio = readl(&clk->div_fsys1); 808 pre_ratio = readl(&clk->div_fsys1); 809 break; 810 case 2: 811 case 3: 812 ratio = readl(&clk->div_fsys2); 813 pre_ratio = readl(&clk->div_fsys2); 814 break; 815 case 4: 816 ratio = readl(&clk->div_fsys3); 817 pre_ratio = readl(&clk->div_fsys3); 818 break; 819 default: 820 return 0; 821 } 822 823 if (dev_index == 1 || dev_index == 3) 824 shift = 16; 825 826 ratio = (ratio >> shift) & 0xf; 827 pre_ratio = (pre_ratio >> (shift + 8)) & 0xff; 828 uclk = (sclk / (ratio + 1)) / (pre_ratio + 1); 829 830 return uclk; 831 } 832 833 /* exynos4: set the mmc clock */ 834 static void exynos4_set_mmc_clk(int dev_index, unsigned int div) 835 { 836 struct exynos4_clock *clk = 837 (struct exynos4_clock *)samsung_get_base_clock(); 838 unsigned int addr, clear_bit, set_bit; 839 840 /* 841 * CLK_DIV_FSYS1 842 * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24] 843 * CLK_DIV_FSYS2 844 * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24] 845 * CLK_DIV_FSYS3 846 * MMC4_RATIO [3:0] 847 */ 848 if (dev_index < 2) { 849 addr = (unsigned int)&clk->div_fsys1; 850 clear_bit = MASK_PRE_RATIO(dev_index); 851 set_bit = SET_PRE_RATIO(dev_index, div); 852 } else if (dev_index == 4) { 853 addr = (unsigned int)&clk->div_fsys3; 854 dev_index -= 4; 855 /* MMC4 is controlled with the MMC4_RATIO value */ 856 clear_bit = MASK_RATIO(dev_index); 857 set_bit = SET_RATIO(dev_index, div); 858 } else { 859 addr = (unsigned int)&clk->div_fsys2; 860 dev_index -= 2; 861 clear_bit = MASK_PRE_RATIO(dev_index); 862 set_bit = SET_PRE_RATIO(dev_index, div); 863 } 864 865 clrsetbits_le32(addr, clear_bit, set_bit); 866 } 867 868 /* exynos5: set the mmc clock */ 869 static void exynos5_set_mmc_clk(int dev_index, unsigned int div) 870 { 871 struct exynos5_clock *clk = 872 (struct exynos5_clock *)samsung_get_base_clock(); 873 unsigned int addr; 874 875 /* 876 * CLK_DIV_FSYS1 877 * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24] 878 * CLK_DIV_FSYS2 879 * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24] 880 */ 881 if (dev_index < 2) { 882 addr = (unsigned int)&clk->div_fsys1; 883 } else { 884 addr = (unsigned int)&clk->div_fsys2; 885 dev_index -= 2; 886 } 887 888 clrsetbits_le32(addr, 0xff << ((dev_index << 4) + 8), 889 (div & 0xff) << ((dev_index << 4) + 8)); 890 } 891 892 /* exynos5: set the mmc clock */ 893 static void exynos5420_set_mmc_clk(int dev_index, unsigned int div) 894 { 895 struct exynos5420_clock *clk = 896 (struct exynos5420_clock *)samsung_get_base_clock(); 897 unsigned int addr; 898 unsigned int shift; 899 900 /* 901 * CLK_DIV_FSYS1 902 * MMC0_RATIO [9:0] 903 * MMC1_RATIO [19:10] 904 * MMC2_RATIO [29:20] 905 */ 906 addr = (unsigned int)&clk->div_fsys1; 907 shift = dev_index * 10; 908 909 clrsetbits_le32(addr, 0x3ff << shift, (div & 0x3ff) << shift); 910 } 911 912 /* get_lcd_clk: return lcd clock frequency */ 913 static unsigned long exynos4_get_lcd_clk(void) 914 { 915 struct exynos4_clock *clk = 916 (struct exynos4_clock *)samsung_get_base_clock(); 917 unsigned long pclk, sclk; 918 unsigned int sel; 919 unsigned int ratio; 920 921 /* 922 * CLK_SRC_LCD0 923 * FIMD0_SEL [3:0] 924 */ 925 sel = readl(&clk->src_lcd0); 926 sel = sel & 0xf; 927 928 /* 929 * 0x6: SCLK_MPLL 930 * 0x7: SCLK_EPLL 931 * 0x8: SCLK_VPLL 932 */ 933 if (sel == 0x6) 934 sclk = get_pll_clk(MPLL); 935 else if (sel == 0x7) 936 sclk = get_pll_clk(EPLL); 937 else if (sel == 0x8) 938 sclk = get_pll_clk(VPLL); 939 else 940 return 0; 941 942 /* 943 * CLK_DIV_LCD0 944 * FIMD0_RATIO [3:0] 945 */ 946 ratio = readl(&clk->div_lcd0); 947 ratio = ratio & 0xf; 948 949 pclk = sclk / (ratio + 1); 950 951 return pclk; 952 } 953 954 /* get_lcd_clk: return lcd clock frequency */ 955 static unsigned long exynos5_get_lcd_clk(void) 956 { 957 struct exynos5_clock *clk = 958 (struct exynos5_clock *)samsung_get_base_clock(); 959 unsigned long pclk, sclk; 960 unsigned int sel; 961 unsigned int ratio; 962 963 /* 964 * CLK_SRC_LCD0 965 * FIMD0_SEL [3:0] 966 */ 967 sel = readl(&clk->src_disp1_0); 968 sel = sel & 0xf; 969 970 /* 971 * 0x6: SCLK_MPLL 972 * 0x7: SCLK_EPLL 973 * 0x8: SCLK_VPLL 974 */ 975 if (sel == 0x6) 976 sclk = get_pll_clk(MPLL); 977 else if (sel == 0x7) 978 sclk = get_pll_clk(EPLL); 979 else if (sel == 0x8) 980 sclk = get_pll_clk(VPLL); 981 else 982 return 0; 983 984 /* 985 * CLK_DIV_LCD0 986 * FIMD0_RATIO [3:0] 987 */ 988 ratio = readl(&clk->div_disp1_0); 989 ratio = ratio & 0xf; 990 991 pclk = sclk / (ratio + 1); 992 993 return pclk; 994 } 995 996 static unsigned long exynos5420_get_lcd_clk(void) 997 { 998 struct exynos5420_clock *clk = 999 (struct exynos5420_clock *)samsung_get_base_clock(); 1000 unsigned long pclk, sclk; 1001 unsigned int sel; 1002 unsigned int ratio; 1003 1004 /* 1005 * CLK_SRC_DISP10 1006 * FIMD1_SEL [4] 1007 * 0: SCLK_RPLL 1008 * 1: SCLK_SPLL 1009 */ 1010 sel = readl(&clk->src_disp10); 1011 sel &= (1 << 4); 1012 1013 if (sel) 1014 sclk = get_pll_clk(SPLL); 1015 else 1016 sclk = get_pll_clk(RPLL); 1017 1018 /* 1019 * CLK_DIV_DISP10 1020 * FIMD1_RATIO [3:0] 1021 */ 1022 ratio = readl(&clk->div_disp10); 1023 ratio = ratio & 0xf; 1024 1025 pclk = sclk / (ratio + 1); 1026 1027 return pclk; 1028 } 1029 1030 static unsigned long exynos5800_get_lcd_clk(void) 1031 { 1032 struct exynos5420_clock *clk = 1033 (struct exynos5420_clock *)samsung_get_base_clock(); 1034 unsigned long sclk; 1035 unsigned int sel; 1036 unsigned int ratio; 1037 1038 /* 1039 * CLK_SRC_DISP10 1040 * CLKMUX_FIMD1 [6:4] 1041 */ 1042 sel = (readl(&clk->src_disp10) >> 4) & 0x7; 1043 1044 if (sel) { 1045 /* 1046 * Mapping of CLK_SRC_DISP10 CLKMUX_FIMD1 [6:4] values into 1047 * PLLs. The first element is a placeholder to bypass the 1048 * default settig. 1049 */ 1050 const int reg_map[] = {0, CPLL, DPLL, MPLL, SPLL, IPLL, EPLL, 1051 RPLL}; 1052 sclk = get_pll_clk(reg_map[sel]); 1053 } else 1054 sclk = CONFIG_SYS_CLK_FREQ; 1055 /* 1056 * CLK_DIV_DISP10 1057 * FIMD1_RATIO [3:0] 1058 */ 1059 ratio = readl(&clk->div_disp10) & 0xf; 1060 1061 return sclk / (ratio + 1); 1062 } 1063 1064 void exynos4_set_lcd_clk(void) 1065 { 1066 struct exynos4_clock *clk = 1067 (struct exynos4_clock *)samsung_get_base_clock(); 1068 1069 /* 1070 * CLK_GATE_BLOCK 1071 * CLK_CAM [0] 1072 * CLK_TV [1] 1073 * CLK_MFC [2] 1074 * CLK_G3D [3] 1075 * CLK_LCD0 [4] 1076 * CLK_LCD1 [5] 1077 * CLK_GPS [7] 1078 */ 1079 setbits_le32(&clk->gate_block, 1 << 4); 1080 1081 /* 1082 * CLK_SRC_LCD0 1083 * FIMD0_SEL [3:0] 1084 * MDNIE0_SEL [7:4] 1085 * MDNIE_PWM0_SEL [8:11] 1086 * MIPI0_SEL [12:15] 1087 * set lcd0 src clock 0x6: SCLK_MPLL 1088 */ 1089 clrsetbits_le32(&clk->src_lcd0, 0xf, 0x6); 1090 1091 /* 1092 * CLK_GATE_IP_LCD0 1093 * CLK_FIMD0 [0] 1094 * CLK_MIE0 [1] 1095 * CLK_MDNIE0 [2] 1096 * CLK_DSIM0 [3] 1097 * CLK_SMMUFIMD0 [4] 1098 * CLK_PPMULCD0 [5] 1099 * Gating all clocks for FIMD0 1100 */ 1101 setbits_le32(&clk->gate_ip_lcd0, 1 << 0); 1102 1103 /* 1104 * CLK_DIV_LCD0 1105 * FIMD0_RATIO [3:0] 1106 * MDNIE0_RATIO [7:4] 1107 * MDNIE_PWM0_RATIO [11:8] 1108 * MDNIE_PWM_PRE_RATIO [15:12] 1109 * MIPI0_RATIO [19:16] 1110 * MIPI0_PRE_RATIO [23:20] 1111 * set fimd ratio 1112 */ 1113 clrsetbits_le32(&clk->div_lcd0, 0xf, 0x1); 1114 } 1115 1116 void exynos5_set_lcd_clk(void) 1117 { 1118 struct exynos5_clock *clk = 1119 (struct exynos5_clock *)samsung_get_base_clock(); 1120 1121 /* 1122 * CLK_GATE_BLOCK 1123 * CLK_CAM [0] 1124 * CLK_TV [1] 1125 * CLK_MFC [2] 1126 * CLK_G3D [3] 1127 * CLK_LCD0 [4] 1128 * CLK_LCD1 [5] 1129 * CLK_GPS [7] 1130 */ 1131 setbits_le32(&clk->gate_block, 1 << 4); 1132 1133 /* 1134 * CLK_SRC_LCD0 1135 * FIMD0_SEL [3:0] 1136 * MDNIE0_SEL [7:4] 1137 * MDNIE_PWM0_SEL [8:11] 1138 * MIPI0_SEL [12:15] 1139 * set lcd0 src clock 0x6: SCLK_MPLL 1140 */ 1141 clrsetbits_le32(&clk->src_disp1_0, 0xf, 0x6); 1142 1143 /* 1144 * CLK_GATE_IP_LCD0 1145 * CLK_FIMD0 [0] 1146 * CLK_MIE0 [1] 1147 * CLK_MDNIE0 [2] 1148 * CLK_DSIM0 [3] 1149 * CLK_SMMUFIMD0 [4] 1150 * CLK_PPMULCD0 [5] 1151 * Gating all clocks for FIMD0 1152 */ 1153 setbits_le32(&clk->gate_ip_disp1, 1 << 0); 1154 1155 /* 1156 * CLK_DIV_LCD0 1157 * FIMD0_RATIO [3:0] 1158 * MDNIE0_RATIO [7:4] 1159 * MDNIE_PWM0_RATIO [11:8] 1160 * MDNIE_PWM_PRE_RATIO [15:12] 1161 * MIPI0_RATIO [19:16] 1162 * MIPI0_PRE_RATIO [23:20] 1163 * set fimd ratio 1164 */ 1165 clrsetbits_le32(&clk->div_disp1_0, 0xf, 0x0); 1166 } 1167 1168 void exynos5420_set_lcd_clk(void) 1169 { 1170 struct exynos5420_clock *clk = 1171 (struct exynos5420_clock *)samsung_get_base_clock(); 1172 unsigned int cfg; 1173 1174 /* 1175 * CLK_SRC_DISP10 1176 * FIMD1_SEL [4] 1177 * 0: SCLK_RPLL 1178 * 1: SCLK_SPLL 1179 */ 1180 cfg = readl(&clk->src_disp10); 1181 cfg &= ~(0x1 << 4); 1182 cfg |= (0 << 4); 1183 writel(cfg, &clk->src_disp10); 1184 1185 /* 1186 * CLK_DIV_DISP10 1187 * FIMD1_RATIO [3:0] 1188 */ 1189 cfg = readl(&clk->div_disp10); 1190 cfg &= ~(0xf << 0); 1191 cfg |= (0 << 0); 1192 writel(cfg, &clk->div_disp10); 1193 } 1194 1195 void exynos5800_set_lcd_clk(void) 1196 { 1197 struct exynos5420_clock *clk = 1198 (struct exynos5420_clock *)samsung_get_base_clock(); 1199 unsigned int cfg; 1200 1201 /* 1202 * Use RPLL for pixel clock 1203 * CLK_SRC_DISP10 CLKMUX_FIMD1 [6:4] 1204 * ================== 1205 * 111: SCLK_RPLL 1206 */ 1207 cfg = readl(&clk->src_disp10) | (0x7 << 4); 1208 writel(cfg, &clk->src_disp10); 1209 1210 /* 1211 * CLK_DIV_DISP10 1212 * FIMD1_RATIO [3:0] 1213 */ 1214 clrsetbits_le32(&clk->div_disp10, 0xf << 0, 0x0 << 0); 1215 } 1216 1217 void exynos4_set_mipi_clk(void) 1218 { 1219 struct exynos4_clock *clk = 1220 (struct exynos4_clock *)samsung_get_base_clock(); 1221 1222 /* 1223 * CLK_SRC_LCD0 1224 * FIMD0_SEL [3:0] 1225 * MDNIE0_SEL [7:4] 1226 * MDNIE_PWM0_SEL [8:11] 1227 * MIPI0_SEL [12:15] 1228 * set mipi0 src clock 0x6: SCLK_MPLL 1229 */ 1230 clrsetbits_le32(&clk->src_lcd0, 0xf << 12, 0x6 << 12); 1231 1232 /* 1233 * CLK_SRC_MASK_LCD0 1234 * FIMD0_MASK [0] 1235 * MDNIE0_MASK [4] 1236 * MDNIE_PWM0_MASK [8] 1237 * MIPI0_MASK [12] 1238 * set src mask mipi0 0x1: Unmask 1239 */ 1240 setbits_le32(&clk->src_mask_lcd0, 0x1 << 12); 1241 1242 /* 1243 * CLK_GATE_IP_LCD0 1244 * CLK_FIMD0 [0] 1245 * CLK_MIE0 [1] 1246 * CLK_MDNIE0 [2] 1247 * CLK_DSIM0 [3] 1248 * CLK_SMMUFIMD0 [4] 1249 * CLK_PPMULCD0 [5] 1250 * Gating all clocks for MIPI0 1251 */ 1252 setbits_le32(&clk->gate_ip_lcd0, 1 << 3); 1253 1254 /* 1255 * CLK_DIV_LCD0 1256 * FIMD0_RATIO [3:0] 1257 * MDNIE0_RATIO [7:4] 1258 * MDNIE_PWM0_RATIO [11:8] 1259 * MDNIE_PWM_PRE_RATIO [15:12] 1260 * MIPI0_RATIO [19:16] 1261 * MIPI0_PRE_RATIO [23:20] 1262 * set mipi ratio 1263 */ 1264 clrsetbits_le32(&clk->div_lcd0, 0xf << 16, 0x1 << 16); 1265 } 1266 1267 int exynos5_set_epll_clk(unsigned long rate) 1268 { 1269 unsigned int epll_con, epll_con_k; 1270 unsigned int i; 1271 unsigned int lockcnt; 1272 unsigned int start; 1273 struct exynos5_clock *clk = 1274 (struct exynos5_clock *)samsung_get_base_clock(); 1275 1276 epll_con = readl(&clk->epll_con0); 1277 epll_con &= ~((EPLL_CON0_LOCK_DET_EN_MASK << 1278 EPLL_CON0_LOCK_DET_EN_SHIFT) | 1279 EPLL_CON0_MDIV_MASK << EPLL_CON0_MDIV_SHIFT | 1280 EPLL_CON0_PDIV_MASK << EPLL_CON0_PDIV_SHIFT | 1281 EPLL_CON0_SDIV_MASK << EPLL_CON0_SDIV_SHIFT); 1282 1283 for (i = 0; i < ARRAY_SIZE(exynos5_epll_div); i++) { 1284 if (exynos5_epll_div[i].freq_out == rate) 1285 break; 1286 } 1287 1288 if (i == ARRAY_SIZE(exynos5_epll_div)) 1289 return -1; 1290 1291 epll_con_k = exynos5_epll_div[i].k_dsm << 0; 1292 epll_con |= exynos5_epll_div[i].en_lock_det << 1293 EPLL_CON0_LOCK_DET_EN_SHIFT; 1294 epll_con |= exynos5_epll_div[i].m_div << EPLL_CON0_MDIV_SHIFT; 1295 epll_con |= exynos5_epll_div[i].p_div << EPLL_CON0_PDIV_SHIFT; 1296 epll_con |= exynos5_epll_div[i].s_div << EPLL_CON0_SDIV_SHIFT; 1297 1298 /* 1299 * Required period ( in cycles) to genarate a stable clock output. 1300 * The maximum clock time can be up to 3000 * PDIV cycles of PLLs 1301 * frequency input (as per spec) 1302 */ 1303 lockcnt = 3000 * exynos5_epll_div[i].p_div; 1304 1305 writel(lockcnt, &clk->epll_lock); 1306 writel(epll_con, &clk->epll_con0); 1307 writel(epll_con_k, &clk->epll_con1); 1308 1309 start = get_timer(0); 1310 1311 while (!(readl(&clk->epll_con0) & 1312 (0x1 << EXYNOS5_EPLLCON0_LOCKED_SHIFT))) { 1313 if (get_timer(start) > TIMEOUT_EPLL_LOCK) { 1314 debug("%s: Timeout waiting for EPLL lock\n", __func__); 1315 return -1; 1316 } 1317 } 1318 return 0; 1319 } 1320 1321 int exynos5_set_i2s_clk_source(unsigned int i2s_id) 1322 { 1323 struct exynos5_clock *clk = 1324 (struct exynos5_clock *)samsung_get_base_clock(); 1325 unsigned int *audio_ass = (unsigned int *)samsung_get_base_audio_ass(); 1326 1327 if (i2s_id == 0) { 1328 setbits_le32(&clk->src_top2, CLK_SRC_MOUT_EPLL); 1329 clrsetbits_le32(&clk->src_mau, AUDIO0_SEL_MASK, 1330 (CLK_SRC_SCLK_EPLL)); 1331 setbits_le32(audio_ass, AUDIO_CLKMUX_ASS); 1332 } else if (i2s_id == 1) { 1333 clrsetbits_le32(&clk->src_peric1, AUDIO1_SEL_MASK, 1334 (CLK_SRC_SCLK_EPLL)); 1335 } else { 1336 return -1; 1337 } 1338 return 0; 1339 } 1340 1341 int exynos5_set_i2s_clk_prescaler(unsigned int src_frq, 1342 unsigned int dst_frq, 1343 unsigned int i2s_id) 1344 { 1345 struct exynos5_clock *clk = 1346 (struct exynos5_clock *)samsung_get_base_clock(); 1347 unsigned int div; 1348 1349 if ((dst_frq == 0) || (src_frq == 0)) { 1350 debug("%s: Invalid requency input for prescaler\n", __func__); 1351 debug("src frq = %d des frq = %d ", src_frq, dst_frq); 1352 return -1; 1353 } 1354 1355 div = (src_frq / dst_frq); 1356 if (i2s_id == 0) { 1357 if (div > AUDIO_0_RATIO_MASK) { 1358 debug("%s: Frequency ratio is out of range\n", 1359 __func__); 1360 debug("src frq = %d des frq = %d ", src_frq, dst_frq); 1361 return -1; 1362 } 1363 clrsetbits_le32(&clk->div_mau, AUDIO_0_RATIO_MASK, 1364 (div & AUDIO_0_RATIO_MASK)); 1365 } else if (i2s_id == 1) { 1366 if (div > AUDIO_1_RATIO_MASK) { 1367 debug("%s: Frequency ratio is out of range\n", 1368 __func__); 1369 debug("src frq = %d des frq = %d ", src_frq, dst_frq); 1370 return -1; 1371 } 1372 clrsetbits_le32(&clk->div_peric4, AUDIO_1_RATIO_MASK, 1373 (div & AUDIO_1_RATIO_MASK)); 1374 } else { 1375 return -1; 1376 } 1377 return 0; 1378 } 1379 1380 /** 1381 * Linearly searches for the most accurate main and fine stage clock scalars 1382 * (divisors) for a specified target frequency and scalar bit sizes by checking 1383 * all multiples of main_scalar_bits values. Will always return scalars up to or 1384 * slower than target. 1385 * 1386 * @param main_scalar_bits Number of main scalar bits, must be > 0 and < 32 1387 * @param fine_scalar_bits Number of fine scalar bits, must be > 0 and < 32 1388 * @param input_freq Clock frequency to be scaled in Hz 1389 * @param target_freq Desired clock frequency in Hz 1390 * @param best_fine_scalar Pointer to store the fine stage divisor 1391 * 1392 * @return best_main_scalar Main scalar for desired frequency or -1 if none 1393 * found 1394 */ 1395 static int clock_calc_best_scalar(unsigned int main_scaler_bits, 1396 unsigned int fine_scalar_bits, unsigned int input_rate, 1397 unsigned int target_rate, unsigned int *best_fine_scalar) 1398 { 1399 int i; 1400 int best_main_scalar = -1; 1401 unsigned int best_error = target_rate; 1402 const unsigned int cap = (1 << fine_scalar_bits) - 1; 1403 const unsigned int loops = 1 << main_scaler_bits; 1404 1405 debug("Input Rate is %u, Target is %u, Cap is %u\n", input_rate, 1406 target_rate, cap); 1407 1408 assert(best_fine_scalar != NULL); 1409 assert(main_scaler_bits <= fine_scalar_bits); 1410 1411 *best_fine_scalar = 1; 1412 1413 if (input_rate == 0 || target_rate == 0) 1414 return -1; 1415 1416 if (target_rate >= input_rate) 1417 return 1; 1418 1419 for (i = 1; i <= loops; i++) { 1420 const unsigned int effective_div = 1421 max(min(input_rate / i / target_rate, cap), 1U); 1422 const unsigned int effective_rate = input_rate / i / 1423 effective_div; 1424 const int error = target_rate - effective_rate; 1425 1426 debug("%d|effdiv:%u, effrate:%u, error:%d\n", i, effective_div, 1427 effective_rate, error); 1428 1429 if (error >= 0 && error <= best_error) { 1430 best_error = error; 1431 best_main_scalar = i; 1432 *best_fine_scalar = effective_div; 1433 } 1434 } 1435 1436 return best_main_scalar; 1437 } 1438 1439 static int exynos5_set_spi_clk(enum periph_id periph_id, 1440 unsigned int rate) 1441 { 1442 struct exynos5_clock *clk = 1443 (struct exynos5_clock *)samsung_get_base_clock(); 1444 int main; 1445 unsigned int fine; 1446 unsigned shift, pre_shift; 1447 unsigned mask = 0xff; 1448 u32 *reg; 1449 1450 main = clock_calc_best_scalar(4, 8, 400000000, rate, &fine); 1451 if (main < 0) { 1452 debug("%s: Cannot set clock rate for periph %d", 1453 __func__, periph_id); 1454 return -1; 1455 } 1456 main = main - 1; 1457 fine = fine - 1; 1458 1459 switch (periph_id) { 1460 case PERIPH_ID_SPI0: 1461 reg = &clk->div_peric1; 1462 shift = 0; 1463 pre_shift = 8; 1464 break; 1465 case PERIPH_ID_SPI1: 1466 reg = &clk->div_peric1; 1467 shift = 16; 1468 pre_shift = 24; 1469 break; 1470 case PERIPH_ID_SPI2: 1471 reg = &clk->div_peric2; 1472 shift = 0; 1473 pre_shift = 8; 1474 break; 1475 case PERIPH_ID_SPI3: 1476 reg = &clk->sclk_div_isp; 1477 shift = 0; 1478 pre_shift = 4; 1479 break; 1480 case PERIPH_ID_SPI4: 1481 reg = &clk->sclk_div_isp; 1482 shift = 12; 1483 pre_shift = 16; 1484 break; 1485 default: 1486 debug("%s: Unsupported peripheral ID %d\n", __func__, 1487 periph_id); 1488 return -1; 1489 } 1490 clrsetbits_le32(reg, mask << shift, (main & mask) << shift); 1491 clrsetbits_le32(reg, mask << pre_shift, (fine & mask) << pre_shift); 1492 1493 return 0; 1494 } 1495 1496 static int exynos5420_set_spi_clk(enum periph_id periph_id, 1497 unsigned int rate) 1498 { 1499 struct exynos5420_clock *clk = 1500 (struct exynos5420_clock *)samsung_get_base_clock(); 1501 int main; 1502 unsigned int fine; 1503 unsigned shift, pre_shift; 1504 unsigned div_mask = 0xf, pre_div_mask = 0xff; 1505 u32 *reg; 1506 u32 *pre_reg; 1507 1508 main = clock_calc_best_scalar(4, 8, 400000000, rate, &fine); 1509 if (main < 0) { 1510 debug("%s: Cannot set clock rate for periph %d", 1511 __func__, periph_id); 1512 return -1; 1513 } 1514 main = main - 1; 1515 fine = fine - 1; 1516 1517 switch (periph_id) { 1518 case PERIPH_ID_SPI0: 1519 reg = &clk->div_peric1; 1520 shift = 20; 1521 pre_reg = &clk->div_peric4; 1522 pre_shift = 8; 1523 break; 1524 case PERIPH_ID_SPI1: 1525 reg = &clk->div_peric1; 1526 shift = 24; 1527 pre_reg = &clk->div_peric4; 1528 pre_shift = 16; 1529 break; 1530 case PERIPH_ID_SPI2: 1531 reg = &clk->div_peric1; 1532 shift = 28; 1533 pre_reg = &clk->div_peric4; 1534 pre_shift = 24; 1535 break; 1536 case PERIPH_ID_SPI3: 1537 reg = &clk->div_isp1; 1538 shift = 16; 1539 pre_reg = &clk->div_isp1; 1540 pre_shift = 0; 1541 break; 1542 case PERIPH_ID_SPI4: 1543 reg = &clk->div_isp1; 1544 shift = 20; 1545 pre_reg = &clk->div_isp1; 1546 pre_shift = 8; 1547 break; 1548 default: 1549 debug("%s: Unsupported peripheral ID %d\n", __func__, 1550 periph_id); 1551 return -1; 1552 } 1553 1554 clrsetbits_le32(reg, div_mask << shift, (main & div_mask) << shift); 1555 clrsetbits_le32(pre_reg, pre_div_mask << pre_shift, 1556 (fine & pre_div_mask) << pre_shift); 1557 1558 return 0; 1559 } 1560 1561 static unsigned long exynos4_get_i2c_clk(void) 1562 { 1563 struct exynos4_clock *clk = 1564 (struct exynos4_clock *)samsung_get_base_clock(); 1565 unsigned long sclk, aclk_100; 1566 unsigned int ratio; 1567 1568 sclk = get_pll_clk(APLL); 1569 1570 ratio = (readl(&clk->div_top)) >> 4; 1571 ratio &= 0xf; 1572 aclk_100 = sclk / (ratio + 1); 1573 return aclk_100; 1574 } 1575 1576 unsigned long get_pll_clk(int pllreg) 1577 { 1578 if (cpu_is_exynos5()) { 1579 if (proid_is_exynos5420() || proid_is_exynos5800()) 1580 return exynos542x_get_pll_clk(pllreg); 1581 return exynos5_get_pll_clk(pllreg); 1582 } else if (cpu_is_exynos4()) { 1583 if (proid_is_exynos4412()) 1584 return exynos4x12_get_pll_clk(pllreg); 1585 return exynos4_get_pll_clk(pllreg); 1586 } 1587 1588 return 0; 1589 } 1590 1591 unsigned long get_arm_clk(void) 1592 { 1593 if (cpu_is_exynos5()) { 1594 return exynos5_get_arm_clk(); 1595 } else if (cpu_is_exynos4()) { 1596 if (proid_is_exynos4412()) 1597 return exynos4x12_get_arm_clk(); 1598 return exynos4_get_arm_clk(); 1599 } 1600 1601 return 0; 1602 } 1603 1604 unsigned long get_i2c_clk(void) 1605 { 1606 if (cpu_is_exynos5()) 1607 return clock_get_periph_rate(PERIPH_ID_I2C0); 1608 else if (cpu_is_exynos4()) 1609 return exynos4_get_i2c_clk(); 1610 1611 return 0; 1612 } 1613 1614 unsigned long get_pwm_clk(void) 1615 { 1616 if (cpu_is_exynos5()) { 1617 return clock_get_periph_rate(PERIPH_ID_PWM0); 1618 } else if (cpu_is_exynos4()) { 1619 if (proid_is_exynos4412()) 1620 return exynos4x12_get_pwm_clk(); 1621 return exynos4_get_pwm_clk(); 1622 } 1623 1624 return 0; 1625 } 1626 1627 unsigned long get_uart_clk(int dev_index) 1628 { 1629 enum periph_id id; 1630 1631 switch (dev_index) { 1632 case 0: 1633 id = PERIPH_ID_UART0; 1634 break; 1635 case 1: 1636 id = PERIPH_ID_UART1; 1637 break; 1638 case 2: 1639 id = PERIPH_ID_UART2; 1640 break; 1641 case 3: 1642 id = PERIPH_ID_UART3; 1643 break; 1644 default: 1645 debug("%s: invalid UART index %d", __func__, dev_index); 1646 return -1; 1647 } 1648 1649 if (cpu_is_exynos5()) { 1650 return clock_get_periph_rate(id); 1651 } else if (cpu_is_exynos4()) { 1652 if (proid_is_exynos4412()) 1653 return exynos4x12_get_uart_clk(dev_index); 1654 return exynos4_get_uart_clk(dev_index); 1655 } 1656 1657 return 0; 1658 } 1659 1660 unsigned long get_mmc_clk(int dev_index) 1661 { 1662 enum periph_id id; 1663 1664 switch (dev_index) { 1665 case 0: 1666 id = PERIPH_ID_SDMMC0; 1667 break; 1668 case 1: 1669 id = PERIPH_ID_SDMMC1; 1670 break; 1671 case 2: 1672 id = PERIPH_ID_SDMMC2; 1673 break; 1674 case 3: 1675 id = PERIPH_ID_SDMMC3; 1676 break; 1677 default: 1678 debug("%s: invalid MMC index %d", __func__, dev_index); 1679 return -1; 1680 } 1681 1682 if (cpu_is_exynos5()) 1683 return clock_get_periph_rate(id); 1684 else if (cpu_is_exynos4()) 1685 return exynos4_get_mmc_clk(dev_index); 1686 1687 return 0; 1688 } 1689 1690 void set_mmc_clk(int dev_index, unsigned int div) 1691 { 1692 /* If want to set correct value, it needs to substract one from div.*/ 1693 if (div > 0) 1694 div -= 1; 1695 1696 if (cpu_is_exynos5()) { 1697 if (proid_is_exynos5420() || proid_is_exynos5800()) 1698 exynos5420_set_mmc_clk(dev_index, div); 1699 else 1700 exynos5_set_mmc_clk(dev_index, div); 1701 } else if (cpu_is_exynos4()) { 1702 exynos4_set_mmc_clk(dev_index, div); 1703 } 1704 } 1705 1706 unsigned long get_lcd_clk(void) 1707 { 1708 if (cpu_is_exynos4()) { 1709 return exynos4_get_lcd_clk(); 1710 } else if (cpu_is_exynos5()) { 1711 if (proid_is_exynos5420()) 1712 return exynos5420_get_lcd_clk(); 1713 else if (proid_is_exynos5800()) 1714 return exynos5800_get_lcd_clk(); 1715 else 1716 return exynos5_get_lcd_clk(); 1717 } 1718 1719 return 0; 1720 } 1721 1722 void set_lcd_clk(void) 1723 { 1724 if (cpu_is_exynos4()) { 1725 exynos4_set_lcd_clk(); 1726 } else if (cpu_is_exynos5()) { 1727 if (proid_is_exynos5250()) 1728 exynos5_set_lcd_clk(); 1729 else if (proid_is_exynos5420()) 1730 exynos5420_set_lcd_clk(); 1731 else 1732 exynos5800_set_lcd_clk(); 1733 } 1734 } 1735 1736 void set_mipi_clk(void) 1737 { 1738 if (cpu_is_exynos4()) 1739 exynos4_set_mipi_clk(); 1740 } 1741 1742 int set_spi_clk(int periph_id, unsigned int rate) 1743 { 1744 if (cpu_is_exynos5()) { 1745 if (proid_is_exynos5420() || proid_is_exynos5800()) 1746 return exynos5420_set_spi_clk(periph_id, rate); 1747 return exynos5_set_spi_clk(periph_id, rate); 1748 } 1749 1750 return 0; 1751 } 1752 1753 int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq, 1754 unsigned int i2s_id) 1755 { 1756 if (cpu_is_exynos5()) 1757 return exynos5_set_i2s_clk_prescaler(src_frq, dst_frq, i2s_id); 1758 1759 return 0; 1760 } 1761 1762 int set_i2s_clk_source(unsigned int i2s_id) 1763 { 1764 if (cpu_is_exynos5()) 1765 return exynos5_set_i2s_clk_source(i2s_id); 1766 1767 return 0; 1768 } 1769 1770 int set_epll_clk(unsigned long rate) 1771 { 1772 if (cpu_is_exynos5()) 1773 return exynos5_set_epll_clk(rate); 1774 1775 return 0; 1776 } 1777