linux/arch/arm/mach-s5pv210/clock.c
<<
>>
Prefs
   1/* linux/arch/arm/mach-s5pv210/clock.c
   2 *
   3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
   4 *              http://www.samsung.com/
   5 *
   6 * S5PV210 - 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/map.h>
  24
  25#include <plat/cpu-freq.h>
  26#include <mach/regs-clock.h>
  27#include <plat/clock.h>
  28#include <plat/cpu.h>
  29#include <plat/pll.h>
  30#include <plat/s5p-clock.h>
  31#include <plat/clock-clksrc.h>
  32
  33#include "common.h"
  34
  35static unsigned long xtal;
  36
  37static struct clksrc_clk clk_mout_apll = {
  38        .clk    = {
  39                .name           = "mout_apll",
  40        },
  41        .sources        = &clk_src_apll,
  42        .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 0, .size = 1 },
  43};
  44
  45static struct clksrc_clk clk_mout_epll = {
  46        .clk    = {
  47                .name           = "mout_epll",
  48        },
  49        .sources        = &clk_src_epll,
  50        .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 8, .size = 1 },
  51};
  52
  53static struct clksrc_clk clk_mout_mpll = {
  54        .clk = {
  55                .name           = "mout_mpll",
  56        },
  57        .sources        = &clk_src_mpll,
  58        .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 4, .size = 1 },
  59};
  60
  61static struct clk *clkset_armclk_list[] = {
  62        [0] = &clk_mout_apll.clk,
  63        [1] = &clk_mout_mpll.clk,
  64};
  65
  66static struct clksrc_sources clkset_armclk = {
  67        .sources        = clkset_armclk_list,
  68        .nr_sources     = ARRAY_SIZE(clkset_armclk_list),
  69};
  70
  71static struct clksrc_clk clk_armclk = {
  72        .clk    = {
  73                .name           = "armclk",
  74        },
  75        .sources        = &clkset_armclk,
  76        .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 16, .size = 1 },
  77        .reg_div        = { .reg = S5P_CLK_DIV0, .shift = 0, .size = 3 },
  78};
  79
  80static struct clksrc_clk clk_hclk_msys = {
  81        .clk    = {
  82                .name           = "hclk_msys",
  83                .parent         = &clk_armclk.clk,
  84        },
  85        .reg_div        = { .reg = S5P_CLK_DIV0, .shift = 8, .size = 3 },
  86};
  87
  88static struct clksrc_clk clk_pclk_msys = {
  89        .clk    = {
  90                .name           = "pclk_msys",
  91                .parent         = &clk_hclk_msys.clk,
  92        },
  93        .reg_div        = { .reg = S5P_CLK_DIV0, .shift = 12, .size = 3 },
  94};
  95
  96static struct clksrc_clk clk_sclk_a2m = {
  97        .clk    = {
  98                .name           = "sclk_a2m",
  99                .parent         = &clk_mout_apll.clk,
 100        },
 101        .reg_div        = { .reg = S5P_CLK_DIV0, .shift = 4, .size = 3 },
 102};
 103
 104static struct clk *clkset_hclk_sys_list[] = {
 105        [0] = &clk_mout_mpll.clk,
 106        [1] = &clk_sclk_a2m.clk,
 107};
 108
 109static struct clksrc_sources clkset_hclk_sys = {
 110        .sources        = clkset_hclk_sys_list,
 111        .nr_sources     = ARRAY_SIZE(clkset_hclk_sys_list),
 112};
 113
 114static struct clksrc_clk clk_hclk_dsys = {
 115        .clk    = {
 116                .name   = "hclk_dsys",
 117        },
 118        .sources        = &clkset_hclk_sys,
 119        .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 20, .size = 1 },
 120        .reg_div        = { .reg = S5P_CLK_DIV0, .shift = 16, .size = 4 },
 121};
 122
 123static struct clksrc_clk clk_pclk_dsys = {
 124        .clk    = {
 125                .name   = "pclk_dsys",
 126                .parent = &clk_hclk_dsys.clk,
 127        },
 128        .reg_div = { .reg = S5P_CLK_DIV0, .shift = 20, .size = 3 },
 129};
 130
 131static struct clksrc_clk clk_hclk_psys = {
 132        .clk    = {
 133                .name   = "hclk_psys",
 134        },
 135        .sources        = &clkset_hclk_sys,
 136        .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 24, .size = 1 },
 137        .reg_div        = { .reg = S5P_CLK_DIV0, .shift = 24, .size = 4 },
 138};
 139
 140static struct clksrc_clk clk_pclk_psys = {
 141        .clk    = {
 142                .name   = "pclk_psys",
 143                .parent = &clk_hclk_psys.clk,
 144        },
 145        .reg_div        = { .reg = S5P_CLK_DIV0, .shift = 28, .size = 3 },
 146};
 147
 148static int s5pv210_clk_ip0_ctrl(struct clk *clk, int enable)
 149{
 150        return s5p_gatectrl(S5P_CLKGATE_IP0, clk, enable);
 151}
 152
 153static int s5pv210_clk_ip1_ctrl(struct clk *clk, int enable)
 154{
 155        return s5p_gatectrl(S5P_CLKGATE_IP1, clk, enable);
 156}
 157
 158static int s5pv210_clk_ip2_ctrl(struct clk *clk, int enable)
 159{
 160        return s5p_gatectrl(S5P_CLKGATE_IP2, clk, enable);
 161}
 162
 163static int s5pv210_clk_ip3_ctrl(struct clk *clk, int enable)
 164{
 165        return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable);
 166}
 167
 168static int s5pv210_clk_mask0_ctrl(struct clk *clk, int enable)
 169{
 170        return s5p_gatectrl(S5P_CLK_SRC_MASK0, clk, enable);
 171}
 172
 173static int s5pv210_clk_mask1_ctrl(struct clk *clk, int enable)
 174{
 175        return s5p_gatectrl(S5P_CLK_SRC_MASK1, clk, enable);
 176}
 177
 178static int s5pv210_clk_hdmiphy_ctrl(struct clk *clk, int enable)
 179{
 180        return s5p_gatectrl(S5P_HDMI_PHY_CONTROL, clk, enable);
 181}
 182
 183static int exynos4_clk_dac_ctrl(struct clk *clk, int enable)
 184{
 185        return s5p_gatectrl(S5P_DAC_PHY_CONTROL, clk, enable);
 186}
 187
 188static struct clk clk_sclk_hdmi27m = {
 189        .name           = "sclk_hdmi27m",
 190        .rate           = 27000000,
 191};
 192
 193static struct clk clk_sclk_hdmiphy = {
 194        .name           = "sclk_hdmiphy",
 195};
 196
 197static struct clk clk_sclk_usbphy0 = {
 198        .name           = "sclk_usbphy0",
 199};
 200
 201static struct clk clk_sclk_usbphy1 = {
 202        .name           = "sclk_usbphy1",
 203};
 204
 205static struct clk clk_pcmcdclk0 = {
 206        .name           = "pcmcdclk",
 207};
 208
 209static struct clk clk_pcmcdclk1 = {
 210        .name           = "pcmcdclk",
 211};
 212
 213static struct clk clk_pcmcdclk2 = {
 214        .name           = "pcmcdclk",
 215};
 216
 217static struct clk *clkset_vpllsrc_list[] = {
 218        [0] = &clk_fin_vpll,
 219        [1] = &clk_sclk_hdmi27m,
 220};
 221
 222static struct clksrc_sources clkset_vpllsrc = {
 223        .sources        = clkset_vpllsrc_list,
 224        .nr_sources     = ARRAY_SIZE(clkset_vpllsrc_list),
 225};
 226
 227static struct clksrc_clk clk_vpllsrc = {
 228        .clk    = {
 229                .name           = "vpll_src",
 230                .enable         = s5pv210_clk_mask0_ctrl,
 231                .ctrlbit        = (1 << 7),
 232        },
 233        .sources        = &clkset_vpllsrc,
 234        .reg_src        = { .reg = S5P_CLK_SRC1, .shift = 28, .size = 1 },
 235};
 236
 237static struct clk *clkset_sclk_vpll_list[] = {
 238        [0] = &clk_vpllsrc.clk,
 239        [1] = &clk_fout_vpll,
 240};
 241
 242static struct clksrc_sources clkset_sclk_vpll = {
 243        .sources        = clkset_sclk_vpll_list,
 244        .nr_sources     = ARRAY_SIZE(clkset_sclk_vpll_list),
 245};
 246
 247static struct clksrc_clk clk_sclk_vpll = {
 248        .clk    = {
 249                .name           = "sclk_vpll",
 250        },
 251        .sources        = &clkset_sclk_vpll,
 252        .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 12, .size = 1 },
 253};
 254
 255static struct clk *clkset_moutdmc0src_list[] = {
 256        [0] = &clk_sclk_a2m.clk,
 257        [1] = &clk_mout_mpll.clk,
 258        [2] = NULL,
 259        [3] = NULL,
 260};
 261
 262static struct clksrc_sources clkset_moutdmc0src = {
 263        .sources        = clkset_moutdmc0src_list,
 264        .nr_sources     = ARRAY_SIZE(clkset_moutdmc0src_list),
 265};
 266
 267static struct clksrc_clk clk_mout_dmc0 = {
 268        .clk    = {
 269                .name           = "mout_dmc0",
 270        },
 271        .sources        = &clkset_moutdmc0src,
 272        .reg_src        = { .reg = S5P_CLK_SRC6, .shift = 24, .size = 2 },
 273};
 274
 275static struct clksrc_clk clk_sclk_dmc0 = {
 276        .clk    = {
 277                .name           = "sclk_dmc0",
 278                .parent         = &clk_mout_dmc0.clk,
 279        },
 280        .reg_div        = { .reg = S5P_CLK_DIV6, .shift = 28, .size = 4 },
 281};
 282
 283static unsigned long s5pv210_clk_imem_get_rate(struct clk *clk)
 284{
 285        return clk_get_rate(clk->parent) / 2;
 286}
 287
 288static struct clk_ops clk_hclk_imem_ops = {
 289        .get_rate       = s5pv210_clk_imem_get_rate,
 290};
 291
 292static unsigned long s5pv210_clk_fout_apll_get_rate(struct clk *clk)
 293{
 294        return s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508);
 295}
 296
 297static struct clk_ops clk_fout_apll_ops = {
 298        .get_rate       = s5pv210_clk_fout_apll_get_rate,
 299};
 300
 301static struct clk init_clocks_off[] = {
 302        {
 303                .name           = "rot",
 304                .parent         = &clk_hclk_dsys.clk,
 305                .enable         = s5pv210_clk_ip0_ctrl,
 306                .ctrlbit        = (1<<29),
 307        }, {
 308                .name           = "fimc",
 309                .devname        = "s5pv210-fimc.0",
 310                .parent         = &clk_hclk_dsys.clk,
 311                .enable         = s5pv210_clk_ip0_ctrl,
 312                .ctrlbit        = (1 << 24),
 313        }, {
 314                .name           = "fimc",
 315                .devname        = "s5pv210-fimc.1",
 316                .parent         = &clk_hclk_dsys.clk,
 317                .enable         = s5pv210_clk_ip0_ctrl,
 318                .ctrlbit        = (1 << 25),
 319        }, {
 320                .name           = "fimc",
 321                .devname        = "s5pv210-fimc.2",
 322                .parent         = &clk_hclk_dsys.clk,
 323                .enable         = s5pv210_clk_ip0_ctrl,
 324                .ctrlbit        = (1 << 26),
 325        }, {
 326                .name           = "jpeg",
 327                .parent         = &clk_hclk_dsys.clk,
 328                .enable         = s5pv210_clk_ip0_ctrl,
 329                .ctrlbit        = (1 << 28),
 330        }, {
 331                .name           = "mfc",
 332                .devname        = "s5p-mfc",
 333                .parent         = &clk_pclk_psys.clk,
 334                .enable         = s5pv210_clk_ip0_ctrl,
 335                .ctrlbit        = (1 << 16),
 336        }, {
 337                .name           = "dac",
 338                .devname        = "s5p-sdo",
 339                .parent         = &clk_hclk_dsys.clk,
 340                .enable         = s5pv210_clk_ip1_ctrl,
 341                .ctrlbit        = (1 << 10),
 342        }, {
 343                .name           = "mixer",
 344                .devname        = "s5p-mixer",
 345                .parent         = &clk_hclk_dsys.clk,
 346                .enable         = s5pv210_clk_ip1_ctrl,
 347                .ctrlbit        = (1 << 9),
 348        }, {
 349                .name           = "vp",
 350                .devname        = "s5p-mixer",
 351                .parent         = &clk_hclk_dsys.clk,
 352                .enable         = s5pv210_clk_ip1_ctrl,
 353                .ctrlbit        = (1 << 8),
 354        }, {
 355                .name           = "hdmi",
 356                .devname        = "s5pv210-hdmi",
 357                .parent         = &clk_hclk_dsys.clk,
 358                .enable         = s5pv210_clk_ip1_ctrl,
 359                .ctrlbit        = (1 << 11),
 360        }, {
 361                .name           = "hdmiphy",
 362                .devname        = "s5pv210-hdmi",
 363                .enable         = s5pv210_clk_hdmiphy_ctrl,
 364                .ctrlbit        = (1 << 0),
 365        }, {
 366                .name           = "dacphy",
 367                .devname        = "s5p-sdo",
 368                .enable         = exynos4_clk_dac_ctrl,
 369                .ctrlbit        = (1 << 0),
 370        }, {
 371                .name           = "otg",
 372                .parent         = &clk_hclk_psys.clk,
 373                .enable         = s5pv210_clk_ip1_ctrl,
 374                .ctrlbit        = (1<<16),
 375        }, {
 376                .name           = "usb-host",
 377                .parent         = &clk_hclk_psys.clk,
 378                .enable         = s5pv210_clk_ip1_ctrl,
 379                .ctrlbit        = (1<<17),
 380        }, {
 381                .name           = "lcd",
 382                .parent         = &clk_hclk_dsys.clk,
 383                .enable         = s5pv210_clk_ip1_ctrl,
 384                .ctrlbit        = (1<<0),
 385        }, {
 386                .name           = "cfcon",
 387                .parent         = &clk_hclk_psys.clk,
 388                .enable         = s5pv210_clk_ip1_ctrl,
 389                .ctrlbit        = (1<<25),
 390        }, {
 391                .name           = "systimer",
 392                .parent         = &clk_pclk_psys.clk,
 393                .enable         = s5pv210_clk_ip3_ctrl,
 394                .ctrlbit        = (1<<16),
 395        }, {
 396                .name           = "watchdog",
 397                .parent         = &clk_pclk_psys.clk,
 398                .enable         = s5pv210_clk_ip3_ctrl,
 399                .ctrlbit        = (1<<22),
 400        }, {
 401                .name           = "rtc",
 402                .parent         = &clk_pclk_psys.clk,
 403                .enable         = s5pv210_clk_ip3_ctrl,
 404                .ctrlbit        = (1<<15),
 405        }, {
 406                .name           = "i2c",
 407                .devname        = "s3c2440-i2c.0",
 408                .parent         = &clk_pclk_psys.clk,
 409                .enable         = s5pv210_clk_ip3_ctrl,
 410                .ctrlbit        = (1<<7),
 411        }, {
 412                .name           = "i2c",
 413                .devname        = "s3c2440-i2c.1",
 414                .parent         = &clk_pclk_psys.clk,
 415                .enable         = s5pv210_clk_ip3_ctrl,
 416                .ctrlbit        = (1 << 10),
 417        }, {
 418                .name           = "i2c",
 419                .devname        = "s3c2440-i2c.2",
 420                .parent         = &clk_pclk_psys.clk,
 421                .enable         = s5pv210_clk_ip3_ctrl,
 422                .ctrlbit        = (1<<9),
 423        }, {
 424                .name           = "i2c",
 425                .devname        = "s3c2440-hdmiphy-i2c",
 426                .parent         = &clk_pclk_psys.clk,
 427                .enable         = s5pv210_clk_ip3_ctrl,
 428                .ctrlbit        = (1 << 11),
 429        }, {
 430                .name           = "spi",
 431                .devname        = "s5pv210-spi.0",
 432                .parent         = &clk_pclk_psys.clk,
 433                .enable         = s5pv210_clk_ip3_ctrl,
 434                .ctrlbit        = (1<<12),
 435        }, {
 436                .name           = "spi",
 437                .devname        = "s5pv210-spi.1",
 438                .parent         = &clk_pclk_psys.clk,
 439                .enable         = s5pv210_clk_ip3_ctrl,
 440                .ctrlbit        = (1<<13),
 441        }, {
 442                .name           = "spi",
 443                .devname        = "s5pv210-spi.2",
 444                .parent         = &clk_pclk_psys.clk,
 445                .enable         = s5pv210_clk_ip3_ctrl,
 446                .ctrlbit        = (1<<14),
 447        }, {
 448                .name           = "timers",
 449                .parent         = &clk_pclk_psys.clk,
 450                .enable         = s5pv210_clk_ip3_ctrl,
 451                .ctrlbit        = (1<<23),
 452        }, {
 453                .name           = "adc",
 454                .parent         = &clk_pclk_psys.clk,
 455                .enable         = s5pv210_clk_ip3_ctrl,
 456                .ctrlbit        = (1<<24),
 457        }, {
 458                .name           = "keypad",
 459                .parent         = &clk_pclk_psys.clk,
 460                .enable         = s5pv210_clk_ip3_ctrl,
 461                .ctrlbit        = (1<<21),
 462        }, {
 463                .name           = "iis",
 464                .devname        = "samsung-i2s.0",
 465                .parent         = &clk_p,
 466                .enable         = s5pv210_clk_ip3_ctrl,
 467                .ctrlbit        = (1<<4),
 468        }, {
 469                .name           = "iis",
 470                .devname        = "samsung-i2s.1",
 471                .parent         = &clk_p,
 472                .enable         = s5pv210_clk_ip3_ctrl,
 473                .ctrlbit        = (1 << 5),
 474        }, {
 475                .name           = "iis",
 476                .devname        = "samsung-i2s.2",
 477                .parent         = &clk_p,
 478                .enable         = s5pv210_clk_ip3_ctrl,
 479                .ctrlbit        = (1 << 6),
 480        }, {
 481                .name           = "spdif",
 482                .parent         = &clk_p,
 483                .enable         = s5pv210_clk_ip3_ctrl,
 484                .ctrlbit        = (1 << 0),
 485        },
 486};
 487
 488static struct clk init_clocks[] = {
 489        {
 490                .name           = "hclk_imem",
 491                .parent         = &clk_hclk_msys.clk,
 492                .ctrlbit        = (1 << 5),
 493                .enable         = s5pv210_clk_ip0_ctrl,
 494                .ops            = &clk_hclk_imem_ops,
 495        }, {
 496                .name           = "uart",
 497                .devname        = "s5pv210-uart.0",
 498                .parent         = &clk_pclk_psys.clk,
 499                .enable         = s5pv210_clk_ip3_ctrl,
 500                .ctrlbit        = (1 << 17),
 501        }, {
 502                .name           = "uart",
 503                .devname        = "s5pv210-uart.1",
 504                .parent         = &clk_pclk_psys.clk,
 505                .enable         = s5pv210_clk_ip3_ctrl,
 506                .ctrlbit        = (1 << 18),
 507        }, {
 508                .name           = "uart",
 509                .devname        = "s5pv210-uart.2",
 510                .parent         = &clk_pclk_psys.clk,
 511                .enable         = s5pv210_clk_ip3_ctrl,
 512                .ctrlbit        = (1 << 19),
 513        }, {
 514                .name           = "uart",
 515                .devname        = "s5pv210-uart.3",
 516                .parent         = &clk_pclk_psys.clk,
 517                .enable         = s5pv210_clk_ip3_ctrl,
 518                .ctrlbit        = (1 << 20),
 519        }, {
 520                .name           = "sromc",
 521                .parent         = &clk_hclk_psys.clk,
 522                .enable         = s5pv210_clk_ip1_ctrl,
 523                .ctrlbit        = (1 << 26),
 524        },
 525};
 526
 527static struct clk clk_hsmmc0 = {
 528        .name           = "hsmmc",
 529        .devname        = "s3c-sdhci.0",
 530        .parent         = &clk_hclk_psys.clk,
 531        .enable         = s5pv210_clk_ip2_ctrl,
 532        .ctrlbit        = (1<<16),
 533};
 534
 535static struct clk clk_hsmmc1 = {
 536        .name           = "hsmmc",
 537        .devname        = "s3c-sdhci.1",
 538        .parent         = &clk_hclk_psys.clk,
 539        .enable         = s5pv210_clk_ip2_ctrl,
 540        .ctrlbit        = (1<<17),
 541};
 542
 543static struct clk clk_hsmmc2 = {
 544        .name           = "hsmmc",
 545        .devname        = "s3c-sdhci.2",
 546        .parent         = &clk_hclk_psys.clk,
 547        .enable         = s5pv210_clk_ip2_ctrl,
 548        .ctrlbit        = (1<<18),
 549};
 550
 551static struct clk clk_hsmmc3 = {
 552        .name           = "hsmmc",
 553        .devname        = "s3c-sdhci.3",
 554        .parent         = &clk_hclk_psys.clk,
 555        .enable         = s5pv210_clk_ip2_ctrl,
 556        .ctrlbit        = (1<<19),
 557};
 558
 559static struct clk clk_pdma0 = {
 560        .name           = "pdma0",
 561        .parent         = &clk_hclk_psys.clk,
 562        .enable         = s5pv210_clk_ip0_ctrl,
 563        .ctrlbit        = (1 << 3),
 564};
 565
 566static struct clk clk_pdma1 = {
 567        .name           = "pdma1",
 568        .parent         = &clk_hclk_psys.clk,
 569        .enable         = s5pv210_clk_ip0_ctrl,
 570        .ctrlbit        = (1 << 4),
 571};
 572
 573static struct clk *clkset_uart_list[] = {
 574        [6] = &clk_mout_mpll.clk,
 575        [7] = &clk_mout_epll.clk,
 576};
 577
 578static struct clksrc_sources clkset_uart = {
 579        .sources        = clkset_uart_list,
 580        .nr_sources     = ARRAY_SIZE(clkset_uart_list),
 581};
 582
 583static struct clk *clkset_group1_list[] = {
 584        [0] = &clk_sclk_a2m.clk,
 585        [1] = &clk_mout_mpll.clk,
 586        [2] = &clk_mout_epll.clk,
 587        [3] = &clk_sclk_vpll.clk,
 588};
 589
 590static struct clksrc_sources clkset_group1 = {
 591        .sources        = clkset_group1_list,
 592        .nr_sources     = ARRAY_SIZE(clkset_group1_list),
 593};
 594
 595static struct clk *clkset_sclk_onenand_list[] = {
 596        [0] = &clk_hclk_psys.clk,
 597        [1] = &clk_hclk_dsys.clk,
 598};
 599
 600static struct clksrc_sources clkset_sclk_onenand = {
 601        .sources        = clkset_sclk_onenand_list,
 602        .nr_sources     = ARRAY_SIZE(clkset_sclk_onenand_list),
 603};
 604
 605static struct clk *clkset_sclk_dac_list[] = {
 606        [0] = &clk_sclk_vpll.clk,
 607        [1] = &clk_sclk_hdmiphy,
 608};
 609
 610static struct clksrc_sources clkset_sclk_dac = {
 611        .sources        = clkset_sclk_dac_list,
 612        .nr_sources     = ARRAY_SIZE(clkset_sclk_dac_list),
 613};
 614
 615static struct clksrc_clk clk_sclk_dac = {
 616        .clk            = {
 617                .name           = "sclk_dac",
 618                .enable         = s5pv210_clk_mask0_ctrl,
 619                .ctrlbit        = (1 << 2),
 620        },
 621        .sources        = &clkset_sclk_dac,
 622        .reg_src        = { .reg = S5P_CLK_SRC1, .shift = 8, .size = 1 },
 623};
 624
 625static struct clksrc_clk clk_sclk_pixel = {
 626        .clk            = {
 627                .name           = "sclk_pixel",
 628                .parent         = &clk_sclk_vpll.clk,
 629        },
 630        .reg_div        = { .reg = S5P_CLK_DIV1, .shift = 0, .size = 4},
 631};
 632
 633static struct clk *clkset_sclk_hdmi_list[] = {
 634        [0] = &clk_sclk_pixel.clk,
 635        [1] = &clk_sclk_hdmiphy,
 636};
 637
 638static struct clksrc_sources clkset_sclk_hdmi = {
 639        .sources        = clkset_sclk_hdmi_list,
 640        .nr_sources     = ARRAY_SIZE(clkset_sclk_hdmi_list),
 641};
 642
 643static struct clksrc_clk clk_sclk_hdmi = {
 644        .clk            = {
 645                .name           = "sclk_hdmi",
 646                .enable         = s5pv210_clk_mask0_ctrl,
 647                .ctrlbit        = (1 << 0),
 648        },
 649        .sources        = &clkset_sclk_hdmi,
 650        .reg_src        = { .reg = S5P_CLK_SRC1, .shift = 0, .size = 1 },
 651};
 652
 653static struct clk *clkset_sclk_mixer_list[] = {
 654        [0] = &clk_sclk_dac.clk,
 655        [1] = &clk_sclk_hdmi.clk,
 656};
 657
 658static struct clksrc_sources clkset_sclk_mixer = {
 659        .sources        = clkset_sclk_mixer_list,
 660        .nr_sources     = ARRAY_SIZE(clkset_sclk_mixer_list),
 661};
 662
 663static struct clksrc_clk clk_sclk_mixer = {
 664        .clk            = {
 665                .name           = "sclk_mixer",
 666                .enable         = s5pv210_clk_mask0_ctrl,
 667                .ctrlbit        = (1 << 1),
 668        },
 669        .sources = &clkset_sclk_mixer,
 670        .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 1 },
 671};
 672
 673static struct clksrc_clk *sclk_tv[] = {
 674        &clk_sclk_dac,
 675        &clk_sclk_pixel,
 676        &clk_sclk_hdmi,
 677        &clk_sclk_mixer,
 678};
 679
 680static struct clk *clkset_sclk_audio0_list[] = {
 681        [0] = &clk_ext_xtal_mux,
 682        [1] = &clk_pcmcdclk0,
 683        [2] = &clk_sclk_hdmi27m,
 684        [3] = &clk_sclk_usbphy0,
 685        [4] = &clk_sclk_usbphy1,
 686        [5] = &clk_sclk_hdmiphy,
 687        [6] = &clk_mout_mpll.clk,
 688        [7] = &clk_mout_epll.clk,
 689        [8] = &clk_sclk_vpll.clk,
 690};
 691
 692static struct clksrc_sources clkset_sclk_audio0 = {
 693        .sources        = clkset_sclk_audio0_list,
 694        .nr_sources     = ARRAY_SIZE(clkset_sclk_audio0_list),
 695};
 696
 697static struct clksrc_clk clk_sclk_audio0 = {
 698        .clk            = {
 699                .name           = "sclk_audio",
 700                .devname        = "soc-audio.0",
 701                .enable         = s5pv210_clk_mask0_ctrl,
 702                .ctrlbit        = (1 << 24),
 703        },
 704        .sources = &clkset_sclk_audio0,
 705        .reg_src = { .reg = S5P_CLK_SRC6, .shift = 0, .size = 4 },
 706        .reg_div = { .reg = S5P_CLK_DIV6, .shift = 0, .size = 4 },
 707};
 708
 709static struct clk *clkset_sclk_audio1_list[] = {
 710        [0] = &clk_ext_xtal_mux,
 711        [1] = &clk_pcmcdclk1,
 712        [2] = &clk_sclk_hdmi27m,
 713        [3] = &clk_sclk_usbphy0,
 714        [4] = &clk_sclk_usbphy1,
 715        [5] = &clk_sclk_hdmiphy,
 716        [6] = &clk_mout_mpll.clk,
 717        [7] = &clk_mout_epll.clk,
 718        [8] = &clk_sclk_vpll.clk,
 719};
 720
 721static struct clksrc_sources clkset_sclk_audio1 = {
 722        .sources        = clkset_sclk_audio1_list,
 723        .nr_sources     = ARRAY_SIZE(clkset_sclk_audio1_list),
 724};
 725
 726static struct clksrc_clk clk_sclk_audio1 = {
 727        .clk            = {
 728                .name           = "sclk_audio",
 729                .devname        = "soc-audio.1",
 730                .enable         = s5pv210_clk_mask0_ctrl,
 731                .ctrlbit        = (1 << 25),
 732        },
 733        .sources = &clkset_sclk_audio1,
 734        .reg_src = { .reg = S5P_CLK_SRC6, .shift = 4, .size = 4 },
 735        .reg_div = { .reg = S5P_CLK_DIV6, .shift = 4, .size = 4 },
 736};
 737
 738static struct clk *clkset_sclk_audio2_list[] = {
 739        [0] = &clk_ext_xtal_mux,
 740        [1] = &clk_pcmcdclk0,
 741        [2] = &clk_sclk_hdmi27m,
 742        [3] = &clk_sclk_usbphy0,
 743        [4] = &clk_sclk_usbphy1,
 744        [5] = &clk_sclk_hdmiphy,
 745        [6] = &clk_mout_mpll.clk,
 746        [7] = &clk_mout_epll.clk,
 747        [8] = &clk_sclk_vpll.clk,
 748};
 749
 750static struct clksrc_sources clkset_sclk_audio2 = {
 751        .sources        = clkset_sclk_audio2_list,
 752        .nr_sources     = ARRAY_SIZE(clkset_sclk_audio2_list),
 753};
 754
 755static struct clksrc_clk clk_sclk_audio2 = {
 756        .clk            = {
 757                .name           = "sclk_audio",
 758                .devname        = "soc-audio.2",
 759                .enable         = s5pv210_clk_mask0_ctrl,
 760                .ctrlbit        = (1 << 26),
 761        },
 762        .sources = &clkset_sclk_audio2,
 763        .reg_src = { .reg = S5P_CLK_SRC6, .shift = 8, .size = 4 },
 764        .reg_div = { .reg = S5P_CLK_DIV6, .shift = 8, .size = 4 },
 765};
 766
 767static struct clk *clkset_sclk_spdif_list[] = {
 768        [0] = &clk_sclk_audio0.clk,
 769        [1] = &clk_sclk_audio1.clk,
 770        [2] = &clk_sclk_audio2.clk,
 771};
 772
 773static struct clksrc_sources clkset_sclk_spdif = {
 774        .sources        = clkset_sclk_spdif_list,
 775        .nr_sources     = ARRAY_SIZE(clkset_sclk_spdif_list),
 776};
 777
 778static struct clksrc_clk clk_sclk_spdif = {
 779        .clk            = {
 780                .name           = "sclk_spdif",
 781                .enable         = s5pv210_clk_mask0_ctrl,
 782                .ctrlbit        = (1 << 27),
 783                .ops            = &s5p_sclk_spdif_ops,
 784        },
 785        .sources = &clkset_sclk_spdif,
 786        .reg_src = { .reg = S5P_CLK_SRC6, .shift = 12, .size = 2 },
 787};
 788
 789static struct clk *clkset_group2_list[] = {
 790        [0] = &clk_ext_xtal_mux,
 791        [1] = &clk_xusbxti,
 792        [2] = &clk_sclk_hdmi27m,
 793        [3] = &clk_sclk_usbphy0,
 794        [4] = &clk_sclk_usbphy1,
 795        [5] = &clk_sclk_hdmiphy,
 796        [6] = &clk_mout_mpll.clk,
 797        [7] = &clk_mout_epll.clk,
 798        [8] = &clk_sclk_vpll.clk,
 799};
 800
 801static struct clksrc_sources clkset_group2 = {
 802        .sources        = clkset_group2_list,
 803        .nr_sources     = ARRAY_SIZE(clkset_group2_list),
 804};
 805
 806static struct clksrc_clk clksrcs[] = {
 807        {
 808                .clk    = {
 809                        .name           = "sclk_dmc",
 810                },
 811                .sources = &clkset_group1,
 812                .reg_src = { .reg = S5P_CLK_SRC6, .shift = 24, .size = 2 },
 813                .reg_div = { .reg = S5P_CLK_DIV6, .shift = 28, .size = 4 },
 814        }, {
 815                .clk    = {
 816                        .name           = "sclk_onenand",
 817                },
 818                .sources = &clkset_sclk_onenand,
 819                .reg_src = { .reg = S5P_CLK_SRC0, .shift = 28, .size = 1 },
 820                .reg_div = { .reg = S5P_CLK_DIV6, .shift = 12, .size = 3 },
 821        }, {
 822                .clk    = {
 823                        .name           = "sclk_fimc",
 824                        .devname        = "s5pv210-fimc.0",
 825                        .enable         = s5pv210_clk_mask1_ctrl,
 826                        .ctrlbit        = (1 << 2),
 827                },
 828                .sources = &clkset_group2,
 829                .reg_src = { .reg = S5P_CLK_SRC3, .shift = 12, .size = 4 },
 830                .reg_div = { .reg = S5P_CLK_DIV3, .shift = 12, .size = 4 },
 831        }, {
 832                .clk    = {
 833                        .name           = "sclk_fimc",
 834                        .devname        = "s5pv210-fimc.1",
 835                        .enable         = s5pv210_clk_mask1_ctrl,
 836                        .ctrlbit        = (1 << 3),
 837                },
 838                .sources = &clkset_group2,
 839                .reg_src = { .reg = S5P_CLK_SRC3, .shift = 16, .size = 4 },
 840                .reg_div = { .reg = S5P_CLK_DIV3, .shift = 16, .size = 4 },
 841        }, {
 842                .clk    = {
 843                        .name           = "sclk_fimc",
 844                        .devname        = "s5pv210-fimc.2",
 845                        .enable         = s5pv210_clk_mask1_ctrl,
 846                        .ctrlbit        = (1 << 4),
 847                },
 848                .sources = &clkset_group2,
 849                .reg_src = { .reg = S5P_CLK_SRC3, .shift = 20, .size = 4 },
 850                .reg_div = { .reg = S5P_CLK_DIV3, .shift = 20, .size = 4 },
 851        }, {
 852                .clk            = {
 853                        .name           = "sclk_cam0",
 854                        .enable         = s5pv210_clk_mask0_ctrl,
 855                        .ctrlbit        = (1 << 3),
 856                },
 857                .sources = &clkset_group2,
 858                .reg_src = { .reg = S5P_CLK_SRC1, .shift = 12, .size = 4 },
 859                .reg_div = { .reg = S5P_CLK_DIV1, .shift = 12, .size = 4 },
 860        }, {
 861                .clk            = {
 862                        .name           = "sclk_cam1",
 863                        .enable         = s5pv210_clk_mask0_ctrl,
 864                        .ctrlbit        = (1 << 4),
 865                },
 866                .sources = &clkset_group2,
 867                .reg_src = { .reg = S5P_CLK_SRC1, .shift = 16, .size = 4 },
 868                .reg_div = { .reg = S5P_CLK_DIV1, .shift = 16, .size = 4 },
 869        }, {
 870                .clk            = {
 871                        .name           = "sclk_fimd",
 872                        .enable         = s5pv210_clk_mask0_ctrl,
 873                        .ctrlbit        = (1 << 5),
 874                },
 875                .sources = &clkset_group2,
 876                .reg_src = { .reg = S5P_CLK_SRC1, .shift = 20, .size = 4 },
 877                .reg_div = { .reg = S5P_CLK_DIV1, .shift = 20, .size = 4 },
 878        }, {
 879                .clk            = {
 880                        .name           = "sclk_mfc",
 881                        .devname        = "s5p-mfc",
 882                        .enable         = s5pv210_clk_ip0_ctrl,
 883                        .ctrlbit        = (1 << 16),
 884                },
 885                .sources = &clkset_group1,
 886                .reg_src = { .reg = S5P_CLK_SRC2, .shift = 4, .size = 2 },
 887                .reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 },
 888        }, {
 889                .clk            = {
 890                        .name           = "sclk_g2d",
 891                        .enable         = s5pv210_clk_ip0_ctrl,
 892                        .ctrlbit        = (1 << 12),
 893                },
 894                .sources = &clkset_group1,
 895                .reg_src = { .reg = S5P_CLK_SRC2, .shift = 8, .size = 2 },
 896                .reg_div = { .reg = S5P_CLK_DIV2, .shift = 8, .size = 4 },
 897        }, {
 898                .clk            = {
 899                        .name           = "sclk_g3d",
 900                        .enable         = s5pv210_clk_ip0_ctrl,
 901                        .ctrlbit        = (1 << 8),
 902                },
 903                .sources = &clkset_group1,
 904                .reg_src = { .reg = S5P_CLK_SRC2, .shift = 0, .size = 2 },
 905                .reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 },
 906        }, {
 907                .clk            = {
 908                        .name           = "sclk_csis",
 909                        .enable         = s5pv210_clk_mask0_ctrl,
 910                        .ctrlbit        = (1 << 6),
 911                },
 912                .sources = &clkset_group2,
 913                .reg_src = { .reg = S5P_CLK_SRC1, .shift = 24, .size = 4 },
 914                .reg_div = { .reg = S5P_CLK_DIV1, .shift = 28, .size = 4 },
 915        }, {
 916                .clk            = {
 917                        .name           = "sclk_pwi",
 918                        .enable         = s5pv210_clk_mask0_ctrl,
 919                        .ctrlbit        = (1 << 29),
 920                },
 921                .sources = &clkset_group2,
 922                .reg_src = { .reg = S5P_CLK_SRC6, .shift = 20, .size = 4 },
 923                .reg_div = { .reg = S5P_CLK_DIV6, .shift = 24, .size = 4 },
 924        }, {
 925                .clk            = {
 926                        .name           = "sclk_pwm",
 927                        .enable         = s5pv210_clk_mask0_ctrl,
 928                        .ctrlbit        = (1 << 19),
 929                },
 930                .sources = &clkset_group2,
 931                .reg_src = { .reg = S5P_CLK_SRC5, .shift = 12, .size = 4 },
 932                .reg_div = { .reg = S5P_CLK_DIV5, .shift = 12, .size = 4 },
 933        },
 934};
 935
 936static struct clksrc_clk clk_sclk_uart0 = {
 937        .clk    = {
 938                .name           = "uclk1",
 939                .devname        = "s5pv210-uart.0",
 940                .enable         = s5pv210_clk_mask0_ctrl,
 941                .ctrlbit        = (1 << 12),
 942        },
 943        .sources = &clkset_uart,
 944        .reg_src = { .reg = S5P_CLK_SRC4, .shift = 16, .size = 4 },
 945        .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 },
 946};
 947
 948static struct clksrc_clk clk_sclk_uart1 = {
 949        .clk            = {
 950                .name           = "uclk1",
 951                .devname        = "s5pv210-uart.1",
 952                .enable         = s5pv210_clk_mask0_ctrl,
 953                .ctrlbit        = (1 << 13),
 954        },
 955        .sources = &clkset_uart,
 956        .reg_src = { .reg = S5P_CLK_SRC4, .shift = 20, .size = 4 },
 957        .reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 },
 958};
 959
 960static struct clksrc_clk clk_sclk_uart2 = {
 961        .clk            = {
 962                .name           = "uclk1",
 963                .devname        = "s5pv210-uart.2",
 964                .enable         = s5pv210_clk_mask0_ctrl,
 965                .ctrlbit        = (1 << 14),
 966        },
 967        .sources = &clkset_uart,
 968        .reg_src = { .reg = S5P_CLK_SRC4, .shift = 24, .size = 4 },
 969        .reg_div = { .reg = S5P_CLK_DIV4, .shift = 24, .size = 4 },
 970};
 971
 972static struct clksrc_clk clk_sclk_uart3 = {
 973        .clk            = {
 974                .name           = "uclk1",
 975                .devname        = "s5pv210-uart.3",
 976                .enable         = s5pv210_clk_mask0_ctrl,
 977                .ctrlbit        = (1 << 15),
 978        },
 979        .sources = &clkset_uart,
 980        .reg_src = { .reg = S5P_CLK_SRC4, .shift = 28, .size = 4 },
 981        .reg_div = { .reg = S5P_CLK_DIV4, .shift = 28, .size = 4 },
 982};
 983
 984static struct clksrc_clk clk_sclk_mmc0 = {
 985        .clk            = {
 986                .name           = "sclk_mmc",
 987                .devname        = "s3c-sdhci.0",
 988                .enable         = s5pv210_clk_mask0_ctrl,
 989                .ctrlbit        = (1 << 8),
 990        },
 991        .sources = &clkset_group2,
 992        .reg_src = { .reg = S5P_CLK_SRC4, .shift = 0, .size = 4 },
 993        .reg_div = { .reg = S5P_CLK_DIV4, .shift = 0, .size = 4 },
 994};
 995
 996static struct clksrc_clk clk_sclk_mmc1 = {
 997        .clk            = {
 998                .name           = "sclk_mmc",
 999                .devname        = "s3c-sdhci.1",
1000                .enable         = s5pv210_clk_mask0_ctrl,
1001                .ctrlbit        = (1 << 9),
1002        },
1003        .sources = &clkset_group2,
1004        .reg_src = { .reg = S5P_CLK_SRC4, .shift = 4, .size = 4 },
1005        .reg_div = { .reg = S5P_CLK_DIV4, .shift = 4, .size = 4 },
1006};
1007
1008static struct clksrc_clk clk_sclk_mmc2 = {
1009        .clk            = {
1010                .name           = "sclk_mmc",
1011                .devname        = "s3c-sdhci.2",
1012                .enable         = s5pv210_clk_mask0_ctrl,
1013                .ctrlbit        = (1 << 10),
1014        },
1015        .sources = &clkset_group2,
1016        .reg_src = { .reg = S5P_CLK_SRC4, .shift = 8, .size = 4 },
1017        .reg_div = { .reg = S5P_CLK_DIV4, .shift = 8, .size = 4 },
1018};
1019
1020static struct clksrc_clk clk_sclk_mmc3 = {
1021        .clk            = {
1022                .name           = "sclk_mmc",
1023                .devname        = "s3c-sdhci.3",
1024                .enable         = s5pv210_clk_mask0_ctrl,
1025                .ctrlbit        = (1 << 11),
1026        },
1027        .sources = &clkset_group2,
1028        .reg_src = { .reg = S5P_CLK_SRC4, .shift = 12, .size = 4 },
1029        .reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 },
1030};
1031
1032static struct clksrc_clk clk_sclk_spi0 = {
1033        .clk            = {
1034                .name           = "sclk_spi",
1035                .devname        = "s5pv210-spi.0",
1036                .enable         = s5pv210_clk_mask0_ctrl,
1037                .ctrlbit        = (1 << 16),
1038        },
1039        .sources = &clkset_group2,
1040        .reg_src = { .reg = S5P_CLK_SRC5, .shift = 0, .size = 4 },
1041        .reg_div = { .reg = S5P_CLK_DIV5, .shift = 0, .size = 4 },
1042        };
1043
1044static struct clksrc_clk clk_sclk_spi1 = {
1045        .clk            = {
1046                .name           = "sclk_spi",
1047                .devname        = "s5pv210-spi.1",
1048                .enable         = s5pv210_clk_mask0_ctrl,
1049                .ctrlbit        = (1 << 17),
1050        },
1051        .sources = &clkset_group2,
1052        .reg_src = { .reg = S5P_CLK_SRC5, .shift = 4, .size = 4 },
1053        .reg_div = { .reg = S5P_CLK_DIV5, .shift = 4, .size = 4 },
1054        };
1055
1056
1057static struct clksrc_clk *clksrc_cdev[] = {
1058        &clk_sclk_uart0,
1059        &clk_sclk_uart1,
1060        &clk_sclk_uart2,
1061        &clk_sclk_uart3,
1062        &clk_sclk_mmc0,
1063        &clk_sclk_mmc1,
1064        &clk_sclk_mmc2,
1065        &clk_sclk_mmc3,
1066        &clk_sclk_spi0,
1067        &clk_sclk_spi1,
1068};
1069
1070static struct clk *clk_cdev[] = {
1071        &clk_hsmmc0,
1072        &clk_hsmmc1,
1073        &clk_hsmmc2,
1074        &clk_hsmmc3,
1075        &clk_pdma0,
1076        &clk_pdma1,
1077};
1078
1079/* Clock initialisation code */
1080static struct clksrc_clk *sysclks[] = {
1081        &clk_mout_apll,
1082        &clk_mout_epll,
1083        &clk_mout_mpll,
1084        &clk_armclk,
1085        &clk_hclk_msys,
1086        &clk_sclk_a2m,
1087        &clk_hclk_dsys,
1088        &clk_hclk_psys,
1089        &clk_pclk_msys,
1090        &clk_pclk_dsys,
1091        &clk_pclk_psys,
1092        &clk_vpllsrc,
1093        &clk_sclk_vpll,
1094        &clk_mout_dmc0,
1095        &clk_sclk_dmc0,
1096        &clk_sclk_audio0,
1097        &clk_sclk_audio1,
1098        &clk_sclk_audio2,
1099        &clk_sclk_spdif,
1100};
1101
1102static u32 epll_div[][6] = {
1103        {  48000000, 0, 48, 3, 3, 0 },
1104        {  96000000, 0, 48, 3, 2, 0 },
1105        { 144000000, 1, 72, 3, 2, 0 },
1106        { 192000000, 0, 48, 3, 1, 0 },
1107        { 288000000, 1, 72, 3, 1, 0 },
1108        {  32750000, 1, 65, 3, 4, 35127 },
1109        {  32768000, 1, 65, 3, 4, 35127 },
1110        {  45158400, 0, 45, 3, 3, 10355 },
1111        {  45000000, 0, 45, 3, 3, 10355 },
1112        {  45158000, 0, 45, 3, 3, 10355 },
1113        {  49125000, 0, 49, 3, 3, 9961 },
1114        {  49152000, 0, 49, 3, 3, 9961 },
1115        {  67737600, 1, 67, 3, 3, 48366 },
1116        {  67738000, 1, 67, 3, 3, 48366 },
1117        {  73800000, 1, 73, 3, 3, 47710 },
1118        {  73728000, 1, 73, 3, 3, 47710 },
1119        {  36000000, 1, 32, 3, 4, 0 },
1120        {  60000000, 1, 60, 3, 3, 0 },
1121        {  72000000, 1, 72, 3, 3, 0 },
1122        {  80000000, 1, 80, 3, 3, 0 },
1123        {  84000000, 0, 42, 3, 2, 0 },
1124        {  50000000, 0, 50, 3, 3, 0 },
1125};
1126
1127static int s5pv210_epll_set_rate(struct clk *clk, unsigned long rate)
1128{
1129        unsigned int epll_con, epll_con_k;
1130        unsigned int i;
1131
1132        /* Return if nothing changed */
1133        if (clk->rate == rate)
1134                return 0;
1135
1136        epll_con = __raw_readl(S5P_EPLL_CON);
1137        epll_con_k = __raw_readl(S5P_EPLL_CON1);
1138
1139        epll_con_k &= ~PLL46XX_KDIV_MASK;
1140        epll_con &= ~(1 << 27 |
1141                        PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT |
1142                        PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT |
1143                        PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
1144
1145        for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
1146                if (epll_div[i][0] == rate) {
1147                        epll_con_k |= epll_div[i][5] << 0;
1148                        epll_con |= (epll_div[i][1] << 27 |
1149                                        epll_div[i][2] << PLL46XX_MDIV_SHIFT |
1150                                        epll_div[i][3] << PLL46XX_PDIV_SHIFT |
1151                                        epll_div[i][4] << PLL46XX_SDIV_SHIFT);
1152                        break;
1153                }
1154        }
1155
1156        if (i == ARRAY_SIZE(epll_div)) {
1157                printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n",
1158                                __func__);
1159                return -EINVAL;
1160        }
1161
1162        __raw_writel(epll_con, S5P_EPLL_CON);
1163        __raw_writel(epll_con_k, S5P_EPLL_CON1);
1164
1165        printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
1166                        clk->rate, rate);
1167
1168        clk->rate = rate;
1169
1170        return 0;
1171}
1172
1173static struct clk_ops s5pv210_epll_ops = {
1174        .set_rate = s5pv210_epll_set_rate,
1175        .get_rate = s5p_epll_get_rate,
1176};
1177
1178static u32 vpll_div[][5] = {
1179        {  54000000, 3, 53, 3, 0 },
1180        { 108000000, 3, 53, 2, 0 },
1181};
1182
1183static unsigned long s5pv210_vpll_get_rate(struct clk *clk)
1184{
1185        return clk->rate;
1186}
1187
1188static int s5pv210_vpll_set_rate(struct clk *clk, unsigned long rate)
1189{
1190        unsigned int vpll_con;
1191        unsigned int i;
1192
1193        /* Return if nothing changed */
1194        if (clk->rate == rate)
1195                return 0;
1196
1197        vpll_con = __raw_readl(S5P_VPLL_CON);
1198        vpll_con &= ~(0x1 << 27 |                                       \
1199                        PLL90XX_MDIV_MASK << PLL90XX_MDIV_SHIFT |       \
1200                        PLL90XX_PDIV_MASK << PLL90XX_PDIV_SHIFT |       \
1201                        PLL90XX_SDIV_MASK << PLL90XX_SDIV_SHIFT);
1202
1203        for (i = 0; i < ARRAY_SIZE(vpll_div); i++) {
1204                if (vpll_div[i][0] == rate) {
1205                        vpll_con |= vpll_div[i][1] << PLL90XX_PDIV_SHIFT;
1206                        vpll_con |= vpll_div[i][2] << PLL90XX_MDIV_SHIFT;
1207                        vpll_con |= vpll_div[i][3] << PLL90XX_SDIV_SHIFT;
1208                        vpll_con |= vpll_div[i][4] << 27;
1209                        break;
1210                }
1211        }
1212
1213        if (i == ARRAY_SIZE(vpll_div)) {
1214                printk(KERN_ERR "%s: Invalid Clock VPLL Frequency\n",
1215                                __func__);
1216                return -EINVAL;
1217        }
1218
1219        __raw_writel(vpll_con, S5P_VPLL_CON);
1220
1221        /* Wait for VPLL lock */
1222        while (!(__raw_readl(S5P_VPLL_CON) & (1 << PLL90XX_LOCKED_SHIFT)))
1223                continue;
1224
1225        clk->rate = rate;
1226        return 0;
1227}
1228static struct clk_ops s5pv210_vpll_ops = {
1229        .get_rate = s5pv210_vpll_get_rate,
1230        .set_rate = s5pv210_vpll_set_rate,
1231};
1232
1233void __init_or_cpufreq s5pv210_setup_clocks(void)
1234{
1235        struct clk *xtal_clk;
1236        unsigned long vpllsrc;
1237        unsigned long armclk;
1238        unsigned long hclk_msys;
1239        unsigned long hclk_dsys;
1240        unsigned long hclk_psys;
1241        unsigned long pclk_msys;
1242        unsigned long pclk_dsys;
1243        unsigned long pclk_psys;
1244        unsigned long apll;
1245        unsigned long mpll;
1246        unsigned long epll;
1247        unsigned long vpll;
1248        unsigned int ptr;
1249        u32 clkdiv0, clkdiv1;
1250
1251        /* Set functions for clk_fout_epll */
1252        clk_fout_epll.enable = s5p_epll_enable;
1253        clk_fout_epll.ops = &s5pv210_epll_ops;
1254
1255        printk(KERN_DEBUG "%s: registering clocks\n", __func__);
1256
1257        clkdiv0 = __raw_readl(S5P_CLK_DIV0);
1258        clkdiv1 = __raw_readl(S5P_CLK_DIV1);
1259
1260        printk(KERN_DEBUG "%s: clkdiv0 = %08x, clkdiv1 = %08x\n",
1261                                __func__, clkdiv0, clkdiv1);
1262
1263        xtal_clk = clk_get(NULL, "xtal");
1264        BUG_ON(IS_ERR(xtal_clk));
1265
1266        xtal = clk_get_rate(xtal_clk);
1267        clk_put(xtal_clk);
1268
1269        printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
1270
1271        apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508);
1272        mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502);
1273        epll = s5p_get_pll46xx(xtal, __raw_readl(S5P_EPLL_CON),
1274                                __raw_readl(S5P_EPLL_CON1), pll_4600);
1275        vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
1276        vpll = s5p_get_pll45xx(vpllsrc, __raw_readl(S5P_VPLL_CON), pll_4502);
1277
1278        clk_fout_apll.ops = &clk_fout_apll_ops;
1279        clk_fout_mpll.rate = mpll;
1280        clk_fout_epll.rate = epll;
1281        clk_fout_vpll.ops = &s5pv210_vpll_ops;
1282        clk_fout_vpll.rate = vpll;
1283
1284        printk(KERN_INFO "S5PV210: PLL settings, A=%ld, M=%ld, E=%ld V=%ld",
1285                        apll, mpll, epll, vpll);
1286
1287        armclk = clk_get_rate(&clk_armclk.clk);
1288        hclk_msys = clk_get_rate(&clk_hclk_msys.clk);
1289        hclk_dsys = clk_get_rate(&clk_hclk_dsys.clk);
1290        hclk_psys = clk_get_rate(&clk_hclk_psys.clk);
1291        pclk_msys = clk_get_rate(&clk_pclk_msys.clk);
1292        pclk_dsys = clk_get_rate(&clk_pclk_dsys.clk);
1293        pclk_psys = clk_get_rate(&clk_pclk_psys.clk);
1294
1295        printk(KERN_INFO "S5PV210: ARMCLK=%ld, HCLKM=%ld, HCLKD=%ld\n"
1296                         "HCLKP=%ld, PCLKM=%ld, PCLKD=%ld, PCLKP=%ld\n",
1297                        armclk, hclk_msys, hclk_dsys, hclk_psys,
1298                        pclk_msys, pclk_dsys, pclk_psys);
1299
1300        clk_f.rate = armclk;
1301        clk_h.rate = hclk_psys;
1302        clk_p.rate = pclk_psys;
1303
1304        for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
1305                s3c_set_clksrc(&clksrcs[ptr], true);
1306}
1307
1308static struct clk *clks[] __initdata = {
1309        &clk_sclk_hdmi27m,
1310        &clk_sclk_hdmiphy,
1311        &clk_sclk_usbphy0,
1312        &clk_sclk_usbphy1,
1313        &clk_pcmcdclk0,
1314        &clk_pcmcdclk1,
1315        &clk_pcmcdclk2,
1316};
1317
1318static struct clk_lookup s5pv210_clk_lookup[] = {
1319        CLKDEV_INIT(NULL, "clk_uart_baud0", &clk_p),
1320        CLKDEV_INIT("s5pv210-uart.0", "clk_uart_baud1", &clk_sclk_uart0.clk),
1321        CLKDEV_INIT("s5pv210-uart.1", "clk_uart_baud1", &clk_sclk_uart1.clk),
1322        CLKDEV_INIT("s5pv210-uart.2", "clk_uart_baud1", &clk_sclk_uart2.clk),
1323        CLKDEV_INIT("s5pv210-uart.3", "clk_uart_baud1", &clk_sclk_uart3.clk),
1324        CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.0", &clk_hsmmc0),
1325        CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.0", &clk_hsmmc1),
1326        CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.0", &clk_hsmmc2),
1327        CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.0", &clk_hsmmc3),
1328        CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk),
1329        CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk),
1330        CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk),
1331        CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.2", &clk_sclk_mmc3.clk),
1332        CLKDEV_INIT(NULL, "spi_busclk0", &clk_p),
1333        CLKDEV_INIT("s5pv210-spi.0", "spi_busclk1", &clk_sclk_spi0.clk),
1334        CLKDEV_INIT("s5pv210-spi.1", "spi_busclk1", &clk_sclk_spi1.clk),
1335        CLKDEV_INIT("dma-pl330.0", "apb_pclk", &clk_pdma0),
1336        CLKDEV_INIT("dma-pl330.1", "apb_pclk", &clk_pdma1),
1337};
1338
1339void __init s5pv210_register_clocks(void)
1340{
1341        int ptr;
1342
1343        s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
1344
1345        for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
1346                s3c_register_clksrc(sysclks[ptr], 1);
1347
1348        for (ptr = 0; ptr < ARRAY_SIZE(sclk_tv); ptr++)
1349                s3c_register_clksrc(sclk_tv[ptr], 1);
1350
1351        for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++)
1352                s3c_register_clksrc(clksrc_cdev[ptr], 1);
1353
1354        s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
1355        s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
1356
1357        s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1358        s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1359        clkdev_add_table(s5pv210_clk_lookup, ARRAY_SIZE(s5pv210_clk_lookup));
1360
1361        s3c24xx_register_clocks(clk_cdev, ARRAY_SIZE(clk_cdev));
1362        for (ptr = 0; ptr < ARRAY_SIZE(clk_cdev); ptr++)
1363                s3c_disable_clocks(clk_cdev[ptr], 1);
1364
1365        s3c_pwmclk_init();
1366}
1367