linux/arch/arm/mach-s5p64x0/clock-s5p6450.c
<<
>>
Prefs
   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/sysdev.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#include <plat/s5p6450.h>
  35
  36static struct clksrc_clk clk_mout_dpll = {
  37        .clk    = {
  38                .name           = "mout_dpll",
  39                .id             = -1,
  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                .id             = -1,
 100                .parent         = &clk_mout_epll.clk,
 101        },
 102        .reg_div        = { .reg = S5P64X0_CLK_DIV1, .shift = 24, .size = 4 },
 103};
 104
 105static struct clksrc_clk clk_mout_hclk_sel = {
 106        .clk    = {
 107                .name           = "mout_hclk_sel",
 108                .id             = -1,
 109        },
 110        .sources        = &clkset_hclk_low,
 111        .reg_src        = { .reg = S5P64X0_OTHERS, .shift = 15, .size = 1 },
 112};
 113
 114static struct clk *clkset_hclk_list[] = {
 115        &clk_mout_hclk_sel.clk,
 116        &clk_armclk.clk,
 117};
 118
 119static struct clksrc_sources clkset_hclk = {
 120        .sources        = clkset_hclk_list,
 121        .nr_sources     = ARRAY_SIZE(clkset_hclk_list),
 122};
 123
 124static struct clksrc_clk clk_hclk = {
 125        .clk    = {
 126                .name           = "clk_hclk",
 127                .id             = -1,
 128        },
 129        .sources        = &clkset_hclk,
 130        .reg_src        = { .reg = S5P64X0_OTHERS, .shift = 14, .size = 1 },
 131        .reg_div        = { .reg = S5P64X0_CLK_DIV0, .shift = 8, .size = 4 },
 132};
 133
 134static struct clksrc_clk clk_pclk = {
 135        .clk    = {
 136                .name           = "clk_pclk",
 137                .id             = -1,
 138                .parent         = &clk_hclk.clk,
 139        },
 140        .reg_div = { .reg = S5P64X0_CLK_DIV0, .shift = 12, .size = 4 },
 141};
 142static struct clksrc_clk clk_dout_pwm_ratio0 = {
 143        .clk    = {
 144                .name           = "clk_dout_pwm_ratio0",
 145                .id             = -1,
 146                .parent         = &clk_mout_hclk_sel.clk,
 147        },
 148        .reg_div        = { .reg = S5P64X0_CLK_DIV3, .shift = 16, .size = 4 },
 149};
 150
 151static struct clksrc_clk clk_pclk_to_wdt_pwm = {
 152        .clk    = {
 153                .name           = "clk_pclk_to_wdt_pwm",
 154                .id             = -1,
 155                .parent         = &clk_dout_pwm_ratio0.clk,
 156        },
 157        .reg_div        = { .reg = S5P64X0_CLK_DIV3, .shift = 20, .size = 4 },
 158};
 159
 160static struct clksrc_clk clk_hclk_low = {
 161        .clk    = {
 162                .name           = "clk_hclk_low",
 163                .id             = -1,
 164        },
 165        .sources        = &clkset_hclk_low,
 166        .reg_src        = { .reg = S5P64X0_OTHERS, .shift = 6, .size = 1 },
 167        .reg_div        = { .reg = S5P64X0_CLK_DIV3, .shift = 8, .size = 4 },
 168};
 169
 170static struct clksrc_clk clk_pclk_low = {
 171        .clk    = {
 172                .name           = "clk_pclk_low",
 173                .id             = -1,
 174                .parent         = &clk_hclk_low.clk,
 175        },
 176        .reg_div        = { .reg = S5P64X0_CLK_DIV3, .shift = 12, .size = 4 },
 177};
 178
 179/*
 180 * The following clocks will be disabled during clock initialization. It is
 181 * recommended to keep the following clocks disabled until the driver requests
 182 * for enabling the clock.
 183 */
 184static struct clk init_clocks_off[] = {
 185        {
 186                .name           = "usbhost",
 187                .id             = -1,
 188                .parent         = &clk_hclk_low.clk,
 189                .enable         = s5p64x0_hclk0_ctrl,
 190                .ctrlbit        = (1 << 3),
 191        }, {
 192                .name           = "pdma",
 193                .id             = -1,
 194                .parent         = &clk_hclk_low.clk,
 195                .enable         = s5p64x0_hclk0_ctrl,
 196                .ctrlbit        = (1 << 12),
 197        }, {
 198                .name           = "hsmmc",
 199                .id             = 0,
 200                .parent         = &clk_hclk_low.clk,
 201                .enable         = s5p64x0_hclk0_ctrl,
 202                .ctrlbit        = (1 << 17),
 203        }, {
 204                .name           = "hsmmc",
 205                .id             = 1,
 206                .parent         = &clk_hclk_low.clk,
 207                .enable         = s5p64x0_hclk0_ctrl,
 208                .ctrlbit        = (1 << 18),
 209        }, {
 210                .name           = "hsmmc",
 211                .id             = 2,
 212                .parent         = &clk_hclk_low.clk,
 213                .enable         = s5p64x0_hclk0_ctrl,
 214                .ctrlbit        = (1 << 19),
 215        }, {
 216                .name           = "usbotg",
 217                .id             = -1,
 218                .parent         = &clk_hclk_low.clk,
 219                .enable         = s5p64x0_hclk0_ctrl,
 220                .ctrlbit        = (1 << 20),
 221        }, {
 222                .name           = "lcd",
 223                .id             = -1,
 224                .parent         = &clk_h,
 225                .enable         = s5p64x0_hclk1_ctrl,
 226                .ctrlbit        = (1 << 1),
 227        }, {
 228                .name           = "watchdog",
 229                .id             = -1,
 230                .parent         = &clk_pclk_low.clk,
 231                .enable         = s5p64x0_pclk_ctrl,
 232                .ctrlbit        = (1 << 5),
 233        }, {
 234                .name           = "rtc",
 235                .id             = -1,
 236                .parent         = &clk_pclk_low.clk,
 237                .enable         = s5p64x0_pclk_ctrl,
 238                .ctrlbit        = (1 << 6),
 239        }, {
 240                .name           = "adc",
 241                .id             = -1,
 242                .parent         = &clk_pclk_low.clk,
 243                .enable         = s5p64x0_pclk_ctrl,
 244                .ctrlbit        = (1 << 12),
 245        }, {
 246                .name           = "i2c",
 247                .id             = 0,
 248                .parent         = &clk_pclk_low.clk,
 249                .enable         = s5p64x0_pclk_ctrl,
 250                .ctrlbit        = (1 << 17),
 251        }, {
 252                .name           = "spi",
 253                .id             = 0,
 254                .parent         = &clk_pclk_low.clk,
 255                .enable         = s5p64x0_pclk_ctrl,
 256                .ctrlbit        = (1 << 21),
 257        }, {
 258                .name           = "spi",
 259                .id             = 1,
 260                .parent         = &clk_pclk_low.clk,
 261                .enable         = s5p64x0_pclk_ctrl,
 262                .ctrlbit        = (1 << 22),
 263        }, {
 264                .name           = "iis",
 265                .id             = 0,
 266                .parent         = &clk_pclk_low.clk,
 267                .enable         = s5p64x0_pclk_ctrl,
 268                .ctrlbit        = (1 << 26),
 269        }, {
 270                .name           = "iis",
 271                .id             = 1,
 272                .parent         = &clk_pclk_low.clk,
 273                .enable         = s5p64x0_pclk_ctrl,
 274                .ctrlbit        = (1 << 15),
 275        }, {
 276                .name           = "iis",
 277                .id             = 2,
 278                .parent         = &clk_pclk_low.clk,
 279                .enable         = s5p64x0_pclk_ctrl,
 280                .ctrlbit        = (1 << 16),
 281        }, {
 282                .name           = "i2c",
 283                .id             = 1,
 284                .parent         = &clk_pclk_low.clk,
 285                .enable         = s5p64x0_pclk_ctrl,
 286                .ctrlbit        = (1 << 27),
 287        }, {
 288                .name           = "dmc0",
 289                .id             = -1,
 290                .parent         = &clk_pclk.clk,
 291                .enable         = s5p64x0_pclk_ctrl,
 292                .ctrlbit        = (1 << 30),
 293        }
 294};
 295
 296/*
 297 * The following clocks will be enabled during clock initialization.
 298 */
 299static struct clk init_clocks[] = {
 300        {
 301                .name           = "intc",
 302                .id             = -1,
 303                .parent         = &clk_hclk.clk,
 304                .enable         = s5p64x0_hclk0_ctrl,
 305                .ctrlbit        = (1 << 1),
 306        }, {
 307                .name           = "mem",
 308                .id             = -1,
 309                .parent         = &clk_hclk.clk,
 310                .enable         = s5p64x0_hclk0_ctrl,
 311                .ctrlbit        = (1 << 21),
 312        }, {
 313                .name           = "uart",
 314                .id             = 0,
 315                .parent         = &clk_pclk_low.clk,
 316                .enable         = s5p64x0_pclk_ctrl,
 317                .ctrlbit        = (1 << 1),
 318        }, {
 319                .name           = "uart",
 320                .id             = 1,
 321                .parent         = &clk_pclk_low.clk,
 322                .enable         = s5p64x0_pclk_ctrl,
 323                .ctrlbit        = (1 << 2),
 324        }, {
 325                .name           = "uart",
 326                .id             = 2,
 327                .parent         = &clk_pclk_low.clk,
 328                .enable         = s5p64x0_pclk_ctrl,
 329                .ctrlbit        = (1 << 3),
 330        }, {
 331                .name           = "uart",
 332                .id             = 3,
 333                .parent         = &clk_pclk_low.clk,
 334                .enable         = s5p64x0_pclk_ctrl,
 335                .ctrlbit        = (1 << 4),
 336        }, {
 337                .name           = "timers",
 338                .id             = -1,
 339                .parent         = &clk_pclk_to_wdt_pwm.clk,
 340                .enable         = s5p64x0_pclk_ctrl,
 341                .ctrlbit        = (1 << 7),
 342        }, {
 343                .name           = "gpio",
 344                .id             = -1,
 345                .parent         = &clk_pclk_low.clk,
 346                .enable         = s5p64x0_pclk_ctrl,
 347                .ctrlbit        = (1 << 18),
 348        },
 349};
 350
 351static struct clk *clkset_uart_list[] = {
 352        &clk_dout_epll.clk,
 353        &clk_dout_mpll.clk,
 354};
 355
 356static struct clksrc_sources clkset_uart = {
 357        .sources        = clkset_uart_list,
 358        .nr_sources     = ARRAY_SIZE(clkset_uart_list),
 359};
 360
 361static struct clk *clkset_mali_list[] = {
 362        &clk_mout_epll.clk,
 363        &clk_mout_apll.clk,
 364        &clk_mout_mpll.clk,
 365};
 366
 367static struct clksrc_sources clkset_mali = {
 368        .sources        = clkset_mali_list,
 369        .nr_sources     = ARRAY_SIZE(clkset_mali_list),
 370};
 371
 372static struct clk *clkset_group2_list[] = {
 373        &clk_dout_epll.clk,
 374        &clk_dout_mpll.clk,
 375        &clk_ext_xtal_mux,
 376};
 377
 378static struct clksrc_sources clkset_group2 = {
 379        .sources        = clkset_group2_list,
 380        .nr_sources     = ARRAY_SIZE(clkset_group2_list),
 381};
 382
 383static struct clk *clkset_dispcon_list[] = {
 384        &clk_dout_epll.clk,
 385        &clk_dout_mpll.clk,
 386        &clk_ext_xtal_mux,
 387        &clk_mout_dpll.clk,
 388};
 389
 390static struct clksrc_sources clkset_dispcon = {
 391        .sources        = clkset_dispcon_list,
 392        .nr_sources     = ARRAY_SIZE(clkset_dispcon_list),
 393};
 394
 395static struct clk *clkset_hsmmc44_list[] = {
 396        &clk_dout_epll.clk,
 397        &clk_dout_mpll.clk,
 398        &clk_ext_xtal_mux,
 399        &s5p_clk_27m,
 400        &clk_48m,
 401};
 402
 403static struct clksrc_sources clkset_hsmmc44 = {
 404        .sources        = clkset_hsmmc44_list,
 405        .nr_sources     = ARRAY_SIZE(clkset_hsmmc44_list),
 406};
 407
 408static struct clk *clkset_sclk_audio0_list[] = {
 409        [0] = &clk_dout_epll.clk,
 410        [1] = &clk_dout_mpll.clk,
 411        [2] = &clk_ext_xtal_mux,
 412        [3] = NULL,
 413        [4] = NULL,
 414};
 415
 416static struct clksrc_sources clkset_sclk_audio0 = {
 417        .sources        = clkset_sclk_audio0_list,
 418        .nr_sources     = ARRAY_SIZE(clkset_sclk_audio0_list),
 419};
 420
 421static struct clksrc_clk clk_sclk_audio0 = {
 422        .clk            = {
 423                .name           = "audio-bus",
 424                .id             = -1,
 425                .enable         = s5p64x0_sclk_ctrl,
 426                .ctrlbit        = (1 << 8),
 427                .parent         = &clk_dout_epll.clk,
 428        },
 429        .sources        = &clkset_sclk_audio0,
 430        .reg_src        = { .reg = S5P64X0_CLK_SRC1, .shift = 10, .size = 3 },
 431        .reg_div        = { .reg = S5P64X0_CLK_DIV2, .shift = 8, .size = 4 },
 432};
 433
 434static struct clksrc_clk clksrcs[] = {
 435        {
 436                .clk    = {
 437                        .name           = "sclk_mmc",
 438                        .id             = 0,
 439                        .ctrlbit        = (1 << 24),
 440                        .enable         = s5p64x0_sclk_ctrl,
 441                },
 442                .sources = &clkset_group2,
 443                .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 18, .size = 2 },
 444                .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 0, .size = 4 },
 445        }, {
 446                .clk    = {
 447                        .name           = "sclk_mmc",
 448                        .id             = 1,
 449                        .ctrlbit        = (1 << 25),
 450                        .enable         = s5p64x0_sclk_ctrl,
 451                },
 452                .sources = &clkset_group2,
 453                .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 20, .size = 2 },
 454                .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 4, .size = 4 },
 455        }, {
 456                .clk    = {
 457                        .name           = "sclk_mmc",
 458                        .id             = 2,
 459                        .ctrlbit        = (1 << 26),
 460                        .enable         = s5p64x0_sclk_ctrl,
 461                },
 462                .sources = &clkset_group2,
 463                .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 22, .size = 2 },
 464                .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 },
 465        }, {
 466                .clk    = {
 467                        .name           = "uclk1",
 468                        .id             = -1,
 469                        .ctrlbit        = (1 << 5),
 470                        .enable         = s5p64x0_sclk_ctrl,
 471                },
 472                .sources = &clkset_uart,
 473                .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 },
 474                .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 },
 475        }, {
 476                .clk    = {
 477                        .name           = "sclk_spi",
 478                        .id             = 0,
 479                        .ctrlbit        = (1 << 20),
 480                        .enable         = s5p64x0_sclk_ctrl,
 481                },
 482                .sources = &clkset_group2,
 483                .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 14, .size = 2 },
 484                .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 0, .size = 4 },
 485        }, {
 486                .clk    = {
 487                        .name           = "sclk_spi",
 488                        .id             = 1,
 489                        .ctrlbit        = (1 << 21),
 490                        .enable         = s5p64x0_sclk_ctrl,
 491                },
 492                .sources = &clkset_group2,
 493                .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 16, .size = 2 },
 494                .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 4, .size = 4 },
 495        }, {
 496                .clk    = {
 497                        .name           = "sclk_fimc",
 498                        .id             = -1,
 499                        .ctrlbit        = (1 << 10),
 500                        .enable         = s5p64x0_sclk_ctrl,
 501                },
 502                .sources = &clkset_group2,
 503                .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 26, .size = 2 },
 504                .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 12, .size = 4 },
 505        }, {
 506                .clk    = {
 507                        .name           = "aclk_mali",
 508                        .id             = -1,
 509                        .ctrlbit        = (1 << 2),
 510                        .enable         = s5p64x0_sclk1_ctrl,
 511                },
 512                .sources = &clkset_mali,
 513                .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 8, .size = 2 },
 514                .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 4, .size = 4 },
 515        }, {
 516                .clk    = {
 517                        .name           = "sclk_2d",
 518                        .id             = -1,
 519                        .ctrlbit        = (1 << 12),
 520                        .enable         = s5p64x0_sclk_ctrl,
 521                },
 522                .sources = &clkset_mali,
 523                .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 30, .size = 2 },
 524                .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 20, .size = 4 },
 525        }, {
 526                .clk    = {
 527                        .name           = "sclk_usi",
 528                        .id             = -1,
 529                        .ctrlbit        = (1 << 7),
 530                        .enable         = s5p64x0_sclk_ctrl,
 531                },
 532                .sources = &clkset_group2,
 533                .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 10, .size = 2 },
 534                .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 16, .size = 4 },
 535        }, {
 536                .clk    = {
 537                        .name           = "sclk_camif",
 538                        .id             = -1,
 539                        .ctrlbit        = (1 << 6),
 540                        .enable         = s5p64x0_sclk_ctrl,
 541                },
 542                .sources = &clkset_group2,
 543                .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 28, .size = 2 },
 544                .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 20, .size = 4 },
 545        }, {
 546                .clk    = {
 547                        .name           = "sclk_dispcon",
 548                        .id             = -1,
 549                        .ctrlbit        = (1 << 1),
 550                        .enable         = s5p64x0_sclk1_ctrl,
 551                },
 552                .sources = &clkset_dispcon,
 553                .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 4, .size = 2 },
 554                .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 0, .size = 4 },
 555        }, {
 556                .clk    = {
 557                        .name           = "sclk_hsmmc44",
 558                        .id             = -1,
 559                        .ctrlbit        = (1 << 30),
 560                        .enable         = s5p64x0_sclk_ctrl,
 561                },
 562                .sources = &clkset_hsmmc44,
 563                .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 6, .size = 3 },
 564                .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 28, .size = 4 },
 565        },
 566};
 567
 568/* Clock initialization code */
 569static struct clksrc_clk *sysclks[] = {
 570        &clk_mout_apll,
 571        &clk_mout_epll,
 572        &clk_dout_epll,
 573        &clk_mout_mpll,
 574        &clk_dout_mpll,
 575        &clk_armclk,
 576        &clk_mout_hclk_sel,
 577        &clk_dout_pwm_ratio0,
 578        &clk_pclk_to_wdt_pwm,
 579        &clk_hclk,
 580        &clk_pclk,
 581        &clk_hclk_low,
 582        &clk_pclk_low,
 583        &clk_sclk_audio0,
 584};
 585
 586void __init_or_cpufreq s5p6450_setup_clocks(void)
 587{
 588        struct clk *xtal_clk;
 589
 590        unsigned long xtal;
 591        unsigned long fclk;
 592        unsigned long hclk;
 593        unsigned long hclk_low;
 594        unsigned long pclk;
 595        unsigned long pclk_low;
 596
 597        unsigned long apll;
 598        unsigned long mpll;
 599        unsigned long epll;
 600        unsigned long dpll;
 601        unsigned int ptr;
 602
 603        /* Set S5P6450 functions for clk_fout_epll */
 604
 605        clk_fout_epll.enable = s5p_epll_enable;
 606        clk_fout_epll.ops = &s5p6450_epll_ops;
 607
 608        clk_48m.enable = s5p64x0_clk48m_ctrl;
 609
 610        xtal_clk = clk_get(NULL, "ext_xtal");
 611        BUG_ON(IS_ERR(xtal_clk));
 612
 613        xtal = clk_get_rate(xtal_clk);
 614        clk_put(xtal_clk);
 615
 616        apll = s5p_get_pll45xx(xtal, __raw_readl(S5P64X0_APLL_CON), pll_4502);
 617        mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P64X0_MPLL_CON), pll_4502);
 618        epll = s5p_get_pll90xx(xtal, __raw_readl(S5P64X0_EPLL_CON),
 619                                __raw_readl(S5P64X0_EPLL_CON_K));
 620        dpll = s5p_get_pll46xx(xtal, __raw_readl(S5P6450_DPLL_CON),
 621                                __raw_readl(S5P6450_DPLL_CON_K), pll_4650c);
 622
 623        clk_fout_apll.rate = apll;
 624        clk_fout_mpll.rate = mpll;
 625        clk_fout_epll.rate = epll;
 626        clk_fout_dpll.rate = dpll;
 627
 628        printk(KERN_INFO "S5P6450: PLL settings, A=%ld.%ldMHz, M=%ld.%ldMHz," \
 629                        " E=%ld.%ldMHz, D=%ld.%ldMHz\n",
 630                        print_mhz(apll), print_mhz(mpll), print_mhz(epll),
 631                        print_mhz(dpll));
 632
 633        fclk = clk_get_rate(&clk_armclk.clk);
 634        hclk = clk_get_rate(&clk_hclk.clk);
 635        pclk = clk_get_rate(&clk_pclk.clk);
 636        hclk_low = clk_get_rate(&clk_hclk_low.clk);
 637        pclk_low = clk_get_rate(&clk_pclk_low.clk);
 638
 639        printk(KERN_INFO "S5P6450: HCLK=%ld.%ldMHz, HCLK_LOW=%ld.%ldMHz," \
 640                        " PCLK=%ld.%ldMHz, PCLK_LOW=%ld.%ldMHz\n",
 641                        print_mhz(hclk), print_mhz(hclk_low),
 642                        print_mhz(pclk), print_mhz(pclk_low));
 643
 644        clk_f.rate = fclk;
 645        clk_h.rate = hclk;
 646        clk_p.rate = pclk;
 647
 648        for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
 649                s3c_set_clksrc(&clksrcs[ptr], true);
 650}
 651
 652void __init s5p6450_register_clocks(void)
 653{
 654        int ptr;
 655
 656        for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
 657                s3c_register_clksrc(sysclks[ptr], 1);
 658
 659        s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
 660        s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
 661
 662        s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
 663        s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
 664
 665        s3c_pwmclk_init();
 666}
 667