1/* linux/arch/arm/mach-s5p64x0/clock-s5p6450.c 2 * 3 * Copyright (c) 2010 Samsung Electronics Co., Ltd. 4 * http://www.samsung.com 5 * 6 * S5P6450 - Clock support 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11*/ 12 13#include <linux/init.h> 14#include <linux/module.h> 15#include <linux/kernel.h> 16#include <linux/list.h> 17#include <linux/errno.h> 18#include <linux/err.h> 19#include <linux/clk.h> 20#include <linux/device.h> 21#include <linux/io.h> 22 23#include <mach/hardware.h> 24#include <mach/map.h> 25#include <mach/regs-clock.h> 26#include <mach/s5p64x0-clock.h> 27 28#include <plat/cpu-freq.h> 29#include <plat/clock.h> 30#include <plat/cpu.h> 31#include <plat/pll.h> 32#include <plat/s5p-clock.h> 33#include <plat/clock-clksrc.h> 34 35#include "common.h" 36 37static struct clksrc_clk clk_mout_dpll = { 38 .clk = { 39 .name = "mout_dpll", 40 }, 41 .sources = &clk_src_dpll, 42 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 5, .size = 1 }, 43}; 44 45static u32 epll_div[][5] = { 46 { 133000000, 27307, 55, 2, 2 }, 47 { 100000000, 43691, 41, 2, 2 }, 48 { 480000000, 0, 80, 2, 0 }, 49}; 50 51static int s5p6450_epll_set_rate(struct clk *clk, unsigned long rate) 52{ 53 unsigned int epll_con, epll_con_k; 54 unsigned int i; 55 56 if (clk->rate == rate) /* Return if nothing changed */ 57 return 0; 58 59 epll_con = __raw_readl(S5P64X0_EPLL_CON); 60 epll_con_k = __raw_readl(S5P64X0_EPLL_CON_K); 61 62 epll_con_k &= ~(PLL90XX_KDIV_MASK); 63 epll_con &= ~(PLL90XX_MDIV_MASK | PLL90XX_PDIV_MASK | PLL90XX_SDIV_MASK); 64 65 for (i = 0; i < ARRAY_SIZE(epll_div); i++) { 66 if (epll_div[i][0] == rate) { 67 epll_con_k |= (epll_div[i][1] << PLL90XX_KDIV_SHIFT); 68 epll_con |= (epll_div[i][2] << PLL90XX_MDIV_SHIFT) | 69 (epll_div[i][3] << PLL90XX_PDIV_SHIFT) | 70 (epll_div[i][4] << PLL90XX_SDIV_SHIFT); 71 break; 72 } 73 } 74 75 if (i == ARRAY_SIZE(epll_div)) { 76 printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", __func__); 77 return -EINVAL; 78 } 79 80 __raw_writel(epll_con, S5P64X0_EPLL_CON); 81 __raw_writel(epll_con_k, S5P64X0_EPLL_CON_K); 82 83 printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n", 84 clk->rate, rate); 85 86 clk->rate = rate; 87 88 return 0; 89} 90 91static struct clk_ops s5p6450_epll_ops = { 92 .get_rate = s5p_epll_get_rate, 93 .set_rate = s5p6450_epll_set_rate, 94}; 95 96static struct clksrc_clk clk_dout_epll = { 97 .clk = { 98 .name = "dout_epll", 99 .parent = &clk_mout_epll.clk, 100 }, 101 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 24, .size = 4 }, 102}; 103 104static struct clksrc_clk clk_mout_hclk_sel = { 105 .clk = { 106 .name = "mout_hclk_sel", 107 }, 108 .sources = &clkset_hclk_low, 109 .reg_src = { .reg = S5P64X0_OTHERS, .shift = 15, .size = 1 }, 110}; 111 112static struct clk *clkset_hclk_list[] = { 113 &clk_mout_hclk_sel.clk, 114 &clk_armclk.clk, 115}; 116 117static struct clksrc_sources clkset_hclk = { 118 .sources = clkset_hclk_list, 119 .nr_sources = ARRAY_SIZE(clkset_hclk_list), 120}; 121 122static struct clksrc_clk clk_hclk = { 123 .clk = { 124 .name = "clk_hclk", 125 }, 126 .sources = &clkset_hclk, 127 .reg_src = { .reg = S5P64X0_OTHERS, .shift = 14, .size = 1 }, 128 .reg_div = { .reg = S5P64X0_CLK_DIV0, .shift = 8, .size = 4 }, 129}; 130 131static struct clksrc_clk clk_pclk = { 132 .clk = { 133 .name = "clk_pclk", 134 .parent = &clk_hclk.clk, 135 }, 136 .reg_div = { .reg = S5P64X0_CLK_DIV0, .shift = 12, .size = 4 }, 137}; 138static struct clksrc_clk clk_dout_pwm_ratio0 = { 139 .clk = { 140 .name = "clk_dout_pwm_ratio0", 141 .parent = &clk_mout_hclk_sel.clk, 142 }, 143 .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 16, .size = 4 }, 144}; 145 146static struct clksrc_clk clk_pclk_to_wdt_pwm = { 147 .clk = { 148 .name = "clk_pclk_to_wdt_pwm", 149 .parent = &clk_dout_pwm_ratio0.clk, 150 }, 151 .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 20, .size = 4 }, 152}; 153 154static struct clksrc_clk clk_hclk_low = { 155 .clk = { 156 .name = "clk_hclk_low", 157 }, 158 .sources = &clkset_hclk_low, 159 .reg_src = { .reg = S5P64X0_OTHERS, .shift = 6, .size = 1 }, 160 .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 8, .size = 4 }, 161}; 162 163static struct clksrc_clk clk_pclk_low = { 164 .clk = { 165 .name = "clk_pclk_low", 166 .parent = &clk_hclk_low.clk, 167 }, 168 .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 12, .size = 4 }, 169}; 170 171/* 172 * The following clocks will be disabled during clock initialization. It is 173 * recommended to keep the following clocks disabled until the driver requests 174 * for enabling the clock. 175 */ 176static struct clk init_clocks_off[] = { 177 { 178 .name = "usbhost", 179 .parent = &clk_hclk_low.clk, 180 .enable = s5p64x0_hclk0_ctrl, 181 .ctrlbit = (1 << 3), 182 }, { 183 .name = "dma", 184 .devname = "dma-pl330", 185 .parent = &clk_hclk_low.clk, 186 .enable = s5p64x0_hclk0_ctrl, 187 .ctrlbit = (1 << 12), 188 }, { 189 .name = "hsmmc", 190 .devname = "s3c-sdhci.0", 191 .parent = &clk_hclk_low.clk, 192 .enable = s5p64x0_hclk0_ctrl, 193 .ctrlbit = (1 << 17), 194 }, { 195 .name = "hsmmc", 196 .devname = "s3c-sdhci.1", 197 .parent = &clk_hclk_low.clk, 198 .enable = s5p64x0_hclk0_ctrl, 199 .ctrlbit = (1 << 18), 200 }, { 201 .name = "hsmmc", 202 .devname = "s3c-sdhci.2", 203 .parent = &clk_hclk_low.clk, 204 .enable = s5p64x0_hclk0_ctrl, 205 .ctrlbit = (1 << 19), 206 }, { 207 .name = "usbotg", 208 .parent = &clk_hclk_low.clk, 209 .enable = s5p64x0_hclk0_ctrl, 210 .ctrlbit = (1 << 20), 211 }, { 212 .name = "lcd", 213 .parent = &clk_h, 214 .enable = s5p64x0_hclk1_ctrl, 215 .ctrlbit = (1 << 1), 216 }, { 217 .name = "watchdog", 218 .parent = &clk_pclk_low.clk, 219 .enable = s5p64x0_pclk_ctrl, 220 .ctrlbit = (1 << 5), 221 }, { 222 .name = "rtc", 223 .parent = &clk_pclk_low.clk, 224 .enable = s5p64x0_pclk_ctrl, 225 .ctrlbit = (1 << 6), 226 }, { 227 .name = "adc", 228 .parent = &clk_pclk_low.clk, 229 .enable = s5p64x0_pclk_ctrl, 230 .ctrlbit = (1 << 12), 231 }, { 232 .name = "i2c", 233 .devname = "s3c2440-i2c.0", 234 .parent = &clk_pclk_low.clk, 235 .enable = s5p64x0_pclk_ctrl, 236 .ctrlbit = (1 << 17), 237 }, { 238 .name = "spi", 239 .devname = "s3c64xx-spi.0", 240 .parent = &clk_pclk_low.clk, 241 .enable = s5p64x0_pclk_ctrl, 242 .ctrlbit = (1 << 21), 243 }, { 244 .name = "spi", 245 .devname = "s3c64xx-spi.1", 246 .parent = &clk_pclk_low.clk, 247 .enable = s5p64x0_pclk_ctrl, 248 .ctrlbit = (1 << 22), 249 }, { 250 .name = "iis", 251 .devname = "samsung-i2s.0", 252 .parent = &clk_pclk_low.clk, 253 .enable = s5p64x0_pclk_ctrl, 254 .ctrlbit = (1 << 26), 255 }, { 256 .name = "iis", 257 .devname = "samsung-i2s.1", 258 .parent = &clk_pclk_low.clk, 259 .enable = s5p64x0_pclk_ctrl, 260 .ctrlbit = (1 << 15), 261 }, { 262 .name = "iis", 263 .devname = "samsung-i2s.2", 264 .parent = &clk_pclk_low.clk, 265 .enable = s5p64x0_pclk_ctrl, 266 .ctrlbit = (1 << 16), 267 }, { 268 .name = "i2c", 269 .devname = "s3c2440-i2c.1", 270 .parent = &clk_pclk_low.clk, 271 .enable = s5p64x0_pclk_ctrl, 272 .ctrlbit = (1 << 27), 273 }, { 274 .name = "dmc0", 275 .parent = &clk_pclk.clk, 276 .enable = s5p64x0_pclk_ctrl, 277 .ctrlbit = (1 << 30), 278 } 279}; 280 281/* 282 * The following clocks will be enabled during clock initialization. 283 */ 284static struct clk init_clocks[] = { 285 { 286 .name = "intc", 287 .parent = &clk_hclk.clk, 288 .enable = s5p64x0_hclk0_ctrl, 289 .ctrlbit = (1 << 1), 290 }, { 291 .name = "mem", 292 .parent = &clk_hclk.clk, 293 .enable = s5p64x0_hclk0_ctrl, 294 .ctrlbit = (1 << 21), 295 }, { 296 .name = "uart", 297 .devname = "s3c6400-uart.0", 298 .parent = &clk_pclk_low.clk, 299 .enable = s5p64x0_pclk_ctrl, 300 .ctrlbit = (1 << 1), 301 }, { 302 .name = "uart", 303 .devname = "s3c6400-uart.1", 304 .parent = &clk_pclk_low.clk, 305 .enable = s5p64x0_pclk_ctrl, 306 .ctrlbit = (1 << 2), 307 }, { 308 .name = "uart", 309 .devname = "s3c6400-uart.2", 310 .parent = &clk_pclk_low.clk, 311 .enable = s5p64x0_pclk_ctrl, 312 .ctrlbit = (1 << 3), 313 }, { 314 .name = "uart", 315 .devname = "s3c6400-uart.3", 316 .parent = &clk_pclk_low.clk, 317 .enable = s5p64x0_pclk_ctrl, 318 .ctrlbit = (1 << 4), 319 }, { 320 .name = "timers", 321 .parent = &clk_pclk_to_wdt_pwm.clk, 322 .enable = s5p64x0_pclk_ctrl, 323 .ctrlbit = (1 << 7), 324 }, { 325 .name = "gpio", 326 .parent = &clk_pclk_low.clk, 327 .enable = s5p64x0_pclk_ctrl, 328 .ctrlbit = (1 << 18), 329 }, 330}; 331 332static struct clk *clkset_uart_list[] = { 333 &clk_dout_epll.clk, 334 &clk_dout_mpll.clk, 335}; 336 337static struct clksrc_sources clkset_uart = { 338 .sources = clkset_uart_list, 339 .nr_sources = ARRAY_SIZE(clkset_uart_list), 340}; 341 342static struct clk *clkset_mali_list[] = { 343 &clk_mout_epll.clk, 344 &clk_mout_apll.clk, 345 &clk_mout_mpll.clk, 346}; 347 348static struct clksrc_sources clkset_mali = { 349 .sources = clkset_mali_list, 350 .nr_sources = ARRAY_SIZE(clkset_mali_list), 351}; 352 353static struct clk *clkset_group2_list[] = { 354 &clk_dout_epll.clk, 355 &clk_dout_mpll.clk, 356 &clk_ext_xtal_mux, 357}; 358 359static struct clksrc_sources clkset_group2 = { 360 .sources = clkset_group2_list, 361 .nr_sources = ARRAY_SIZE(clkset_group2_list), 362}; 363 364static struct clk *clkset_dispcon_list[] = { 365 &clk_dout_epll.clk, 366 &clk_dout_mpll.clk, 367 &clk_ext_xtal_mux, 368 &clk_mout_dpll.clk, 369}; 370 371static struct clksrc_sources clkset_dispcon = { 372 .sources = clkset_dispcon_list, 373 .nr_sources = ARRAY_SIZE(clkset_dispcon_list), 374}; 375 376static struct clk *clkset_hsmmc44_list[] = { 377 &clk_dout_epll.clk, 378 &clk_dout_mpll.clk, 379 &clk_ext_xtal_mux, 380 &s5p_clk_27m, 381 &clk_48m, 382}; 383 384static struct clksrc_sources clkset_hsmmc44 = { 385 .sources = clkset_hsmmc44_list, 386 .nr_sources = ARRAY_SIZE(clkset_hsmmc44_list), 387}; 388 389static struct clk *clkset_sclk_audio0_list[] = { 390 [0] = &clk_dout_epll.clk, 391 [1] = &clk_dout_mpll.clk, 392 [2] = &clk_ext_xtal_mux, 393 [3] = NULL, 394 [4] = NULL, 395}; 396 397static struct clksrc_sources clkset_sclk_audio0 = { 398 .sources = clkset_sclk_audio0_list, 399 .nr_sources = ARRAY_SIZE(clkset_sclk_audio0_list), 400}; 401 402static struct clksrc_clk clk_sclk_audio0 = { 403 .clk = { 404 .name = "audio-bus", 405 .enable = s5p64x0_sclk_ctrl, 406 .ctrlbit = (1 << 8), 407 .parent = &clk_dout_epll.clk, 408 }, 409 .sources = &clkset_sclk_audio0, 410 .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 10, .size = 3 }, 411 .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 8, .size = 4 }, 412}; 413 414static struct clksrc_clk clksrcs[] = { 415 { 416 .clk = { 417 .name = "sclk_fimc", 418 .ctrlbit = (1 << 10), 419 .enable = s5p64x0_sclk_ctrl, 420 }, 421 .sources = &clkset_group2, 422 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 26, .size = 2 }, 423 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 12, .size = 4 }, 424 }, { 425 .clk = { 426 .name = "aclk_mali", 427 .ctrlbit = (1 << 2), 428 .enable = s5p64x0_sclk1_ctrl, 429 }, 430 .sources = &clkset_mali, 431 .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 8, .size = 2 }, 432 .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 4, .size = 4 }, 433 }, { 434 .clk = { 435 .name = "sclk_2d", 436 .ctrlbit = (1 << 12), 437 .enable = s5p64x0_sclk_ctrl, 438 }, 439 .sources = &clkset_mali, 440 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 30, .size = 2 }, 441 .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 20, .size = 4 }, 442 }, { 443 .clk = { 444 .name = "sclk_usi", 445 .ctrlbit = (1 << 7), 446 .enable = s5p64x0_sclk_ctrl, 447 }, 448 .sources = &clkset_group2, 449 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 10, .size = 2 }, 450 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 16, .size = 4 }, 451 }, { 452 .clk = { 453 .name = "sclk_camif", 454 .ctrlbit = (1 << 6), 455 .enable = s5p64x0_sclk_ctrl, 456 }, 457 .sources = &clkset_group2, 458 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 28, .size = 2 }, 459 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 20, .size = 4 }, 460 }, { 461 .clk = { 462 .name = "sclk_dispcon", 463 .ctrlbit = (1 << 1), 464 .enable = s5p64x0_sclk1_ctrl, 465 }, 466 .sources = &clkset_dispcon, 467 .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 4, .size = 2 }, 468 .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 0, .size = 4 }, 469 }, { 470 .clk = { 471 .name = "sclk_hsmmc44", 472 .ctrlbit = (1 << 30), 473 .enable = s5p64x0_sclk_ctrl, 474 }, 475 .sources = &clkset_hsmmc44, 476 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 6, .size = 3 }, 477 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 28, .size = 4 }, 478 }, 479}; 480 481static struct clksrc_clk clk_sclk_mmc0 = { 482 .clk = { 483 .name = "sclk_mmc", 484 .devname = "s3c-sdhci.0", 485 .ctrlbit = (1 << 24), 486 .enable = s5p64x0_sclk_ctrl, 487 }, 488 .sources = &clkset_group2, 489 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 18, .size = 2 }, 490 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 0, .size = 4 }, 491}; 492 493static struct clksrc_clk clk_sclk_mmc1 = { 494 .clk = { 495 .name = "sclk_mmc", 496 .devname = "s3c-sdhci.1", 497 .ctrlbit = (1 << 25), 498 .enable = s5p64x0_sclk_ctrl, 499 }, 500 .sources = &clkset_group2, 501 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 20, .size = 2 }, 502 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 4, .size = 4 }, 503}; 504 505static struct clksrc_clk clk_sclk_mmc2 = { 506 .clk = { 507 .name = "sclk_mmc", 508 .devname = "s3c-sdhci.2", 509 .ctrlbit = (1 << 26), 510 .enable = s5p64x0_sclk_ctrl, 511 }, 512 .sources = &clkset_group2, 513 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 22, .size = 2 }, 514 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 }, 515}; 516 517static struct clksrc_clk clk_sclk_uclk = { 518 .clk = { 519 .name = "uclk1", 520 .ctrlbit = (1 << 5), 521 .enable = s5p64x0_sclk_ctrl, 522 }, 523 .sources = &clkset_uart, 524 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 }, 525 .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 }, 526}; 527 528static struct clksrc_clk clk_sclk_spi0 = { 529 .clk = { 530 .name = "sclk_spi", 531 .devname = "s3c64xx-spi.0", 532 .ctrlbit = (1 << 20), 533 .enable = s5p64x0_sclk_ctrl, 534 }, 535 .sources = &clkset_group2, 536 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 14, .size = 2 }, 537 .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 0, .size = 4 }, 538}; 539 540static struct clksrc_clk clk_sclk_spi1 = { 541 .clk = { 542 .name = "sclk_spi", 543 .devname = "s3c64xx-spi.1", 544 .ctrlbit = (1 << 21), 545 .enable = s5p64x0_sclk_ctrl, 546 }, 547 .sources = &clkset_group2, 548 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 16, .size = 2 }, 549 .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 4, .size = 4 }, 550}; 551 552static struct clksrc_clk *clksrc_cdev[] = { 553 &clk_sclk_uclk, 554 &clk_sclk_spi0, 555 &clk_sclk_spi1, 556 &clk_sclk_mmc0, 557 &clk_sclk_mmc1, 558 &clk_sclk_mmc2, 559}; 560 561static struct clk_lookup s5p6450_clk_lookup[] = { 562 CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_pclk_low.clk), 563 CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk), 564 CLKDEV_INIT(NULL, "spi_busclk0", &clk_p), 565 CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk1", &clk_sclk_spi0.clk), 566 CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk1", &clk_sclk_spi1.clk), 567 CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk), 568 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk), 569 CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk), 570}; 571 572/* Clock initialization code */ 573static struct clksrc_clk *sysclks[] = { 574 &clk_mout_apll, 575 &clk_mout_epll, 576 &clk_dout_epll, 577 &clk_mout_mpll, 578 &clk_dout_mpll, 579 &clk_armclk, 580 &clk_mout_hclk_sel, 581 &clk_dout_pwm_ratio0, 582 &clk_pclk_to_wdt_pwm, 583 &clk_hclk, 584 &clk_pclk, 585 &clk_hclk_low, 586 &clk_pclk_low, 587 &clk_sclk_audio0, 588}; 589 590static struct clk dummy_apb_pclk = { 591 .name = "apb_pclk", 592 .id = -1, 593}; 594 595void __init_or_cpufreq s5p6450_setup_clocks(void) 596{ 597 struct clk *xtal_clk; 598 599 unsigned long xtal; 600 unsigned long fclk; 601 unsigned long hclk; 602 unsigned long hclk_low; 603 unsigned long pclk; 604 unsigned long pclk_low; 605 606 unsigned long apll; 607 unsigned long mpll; 608 unsigned long epll; 609 unsigned long dpll; 610 unsigned int ptr; 611 612 /* Set S5P6450 functions for clk_fout_epll */ 613 614 clk_fout_epll.enable = s5p_epll_enable; 615 clk_fout_epll.ops = &s5p6450_epll_ops; 616 617 clk_48m.enable = s5p64x0_clk48m_ctrl; 618 619 xtal_clk = clk_get(NULL, "ext_xtal"); 620 BUG_ON(IS_ERR(xtal_clk)); 621 622 xtal = clk_get_rate(xtal_clk); 623 clk_put(xtal_clk); 624 625 apll = s5p_get_pll45xx(xtal, __raw_readl(S5P64X0_APLL_CON), pll_4502); 626 mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P64X0_MPLL_CON), pll_4502); 627 epll = s5p_get_pll90xx(xtal, __raw_readl(S5P64X0_EPLL_CON), 628 __raw_readl(S5P64X0_EPLL_CON_K)); 629 dpll = s5p_get_pll46xx(xtal, __raw_readl(S5P6450_DPLL_CON), 630 __raw_readl(S5P6450_DPLL_CON_K), pll_4650c); 631 632 clk_fout_apll.rate = apll; 633 clk_fout_mpll.rate = mpll; 634 clk_fout_epll.rate = epll; 635 clk_fout_dpll.rate = dpll; 636 637 printk(KERN_INFO "S5P6450: PLL settings, A=%ld.%ldMHz, M=%ld.%ldMHz," \ 638 " E=%ld.%ldMHz, D=%ld.%ldMHz\n", 639 print_mhz(apll), print_mhz(mpll), print_mhz(epll), 640 print_mhz(dpll)); 641 642 fclk = clk_get_rate(&clk_armclk.clk); 643 hclk = clk_get_rate(&clk_hclk.clk); 644 pclk = clk_get_rate(&clk_pclk.clk); 645 hclk_low = clk_get_rate(&clk_hclk_low.clk); 646 pclk_low = clk_get_rate(&clk_pclk_low.clk); 647 648 printk(KERN_INFO "S5P6450: HCLK=%ld.%ldMHz, HCLK_LOW=%ld.%ldMHz," \ 649 " PCLK=%ld.%ldMHz, PCLK_LOW=%ld.%ldMHz\n", 650 print_mhz(hclk), print_mhz(hclk_low), 651 print_mhz(pclk), print_mhz(pclk_low)); 652 653 clk_f.rate = fclk; 654 clk_h.rate = hclk; 655 clk_p.rate = pclk; 656 657 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) 658 s3c_set_clksrc(&clksrcs[ptr], true); 659} 660 661void __init s5p6450_register_clocks(void) 662{ 663 int ptr; 664 665 for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++) 666 s3c_register_clksrc(sysclks[ptr], 1); 667 668 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); 669 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); 670 for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++) 671 s3c_register_clksrc(clksrc_cdev[ptr], 1); 672 673 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 674 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 675 clkdev_add_table(s5p6450_clk_lookup, ARRAY_SIZE(s5p6450_clk_lookup)); 676 677 s3c24xx_register_clock(&dummy_apb_pclk); 678 679 s3c_pwmclk_init(); 680} 681