linux/arch/arm/mach-exynos/clock.c
<<
>>
Prefs
   1/* linux/arch/arm/mach-exynos4/clock.c
   2 *
   3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
   4 *              http://www.samsung.com
   5 *
   6 * EXYNOS4 - 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/kernel.h>
  14#include <linux/err.h>
  15#include <linux/io.h>
  16#include <linux/syscore_ops.h>
  17
  18#include <plat/cpu-freq.h>
  19#include <plat/clock.h>
  20#include <plat/cpu.h>
  21#include <plat/pll.h>
  22#include <plat/s5p-clock.h>
  23#include <plat/clock-clksrc.h>
  24#include <plat/exynos4.h>
  25#include <plat/pm.h>
  26
  27#include <mach/map.h>
  28#include <mach/regs-clock.h>
  29#include <mach/sysmmu.h>
  30#include <mach/exynos4-clock.h>
  31
  32static struct sleep_save exynos4_clock_save[] = {
  33        SAVE_ITEM(S5P_CLKDIV_LEFTBUS),
  34        SAVE_ITEM(S5P_CLKGATE_IP_LEFTBUS),
  35        SAVE_ITEM(S5P_CLKDIV_RIGHTBUS),
  36        SAVE_ITEM(S5P_CLKGATE_IP_RIGHTBUS),
  37        SAVE_ITEM(S5P_CLKSRC_TOP0),
  38        SAVE_ITEM(S5P_CLKSRC_TOP1),
  39        SAVE_ITEM(S5P_CLKSRC_CAM),
  40        SAVE_ITEM(S5P_CLKSRC_TV),
  41        SAVE_ITEM(S5P_CLKSRC_MFC),
  42        SAVE_ITEM(S5P_CLKSRC_G3D),
  43        SAVE_ITEM(S5P_CLKSRC_LCD0),
  44        SAVE_ITEM(S5P_CLKSRC_MAUDIO),
  45        SAVE_ITEM(S5P_CLKSRC_FSYS),
  46        SAVE_ITEM(S5P_CLKSRC_PERIL0),
  47        SAVE_ITEM(S5P_CLKSRC_PERIL1),
  48        SAVE_ITEM(S5P_CLKDIV_CAM),
  49        SAVE_ITEM(S5P_CLKDIV_TV),
  50        SAVE_ITEM(S5P_CLKDIV_MFC),
  51        SAVE_ITEM(S5P_CLKDIV_G3D),
  52        SAVE_ITEM(S5P_CLKDIV_LCD0),
  53        SAVE_ITEM(S5P_CLKDIV_MAUDIO),
  54        SAVE_ITEM(S5P_CLKDIV_FSYS0),
  55        SAVE_ITEM(S5P_CLKDIV_FSYS1),
  56        SAVE_ITEM(S5P_CLKDIV_FSYS2),
  57        SAVE_ITEM(S5P_CLKDIV_FSYS3),
  58        SAVE_ITEM(S5P_CLKDIV_PERIL0),
  59        SAVE_ITEM(S5P_CLKDIV_PERIL1),
  60        SAVE_ITEM(S5P_CLKDIV_PERIL2),
  61        SAVE_ITEM(S5P_CLKDIV_PERIL3),
  62        SAVE_ITEM(S5P_CLKDIV_PERIL4),
  63        SAVE_ITEM(S5P_CLKDIV_PERIL5),
  64        SAVE_ITEM(S5P_CLKDIV_TOP),
  65        SAVE_ITEM(S5P_CLKSRC_MASK_TOP),
  66        SAVE_ITEM(S5P_CLKSRC_MASK_CAM),
  67        SAVE_ITEM(S5P_CLKSRC_MASK_TV),
  68        SAVE_ITEM(S5P_CLKSRC_MASK_LCD0),
  69        SAVE_ITEM(S5P_CLKSRC_MASK_MAUDIO),
  70        SAVE_ITEM(S5P_CLKSRC_MASK_FSYS),
  71        SAVE_ITEM(S5P_CLKSRC_MASK_PERIL0),
  72        SAVE_ITEM(S5P_CLKSRC_MASK_PERIL1),
  73        SAVE_ITEM(S5P_CLKDIV2_RATIO),
  74        SAVE_ITEM(S5P_CLKGATE_SCLKCAM),
  75        SAVE_ITEM(S5P_CLKGATE_IP_CAM),
  76        SAVE_ITEM(S5P_CLKGATE_IP_TV),
  77        SAVE_ITEM(S5P_CLKGATE_IP_MFC),
  78        SAVE_ITEM(S5P_CLKGATE_IP_G3D),
  79        SAVE_ITEM(S5P_CLKGATE_IP_LCD0),
  80        SAVE_ITEM(S5P_CLKGATE_IP_FSYS),
  81        SAVE_ITEM(S5P_CLKGATE_IP_GPS),
  82        SAVE_ITEM(S5P_CLKGATE_IP_PERIL),
  83        SAVE_ITEM(S5P_CLKGATE_BLOCK),
  84        SAVE_ITEM(S5P_CLKSRC_MASK_DMC),
  85        SAVE_ITEM(S5P_CLKSRC_DMC),
  86        SAVE_ITEM(S5P_CLKDIV_DMC0),
  87        SAVE_ITEM(S5P_CLKDIV_DMC1),
  88        SAVE_ITEM(S5P_CLKGATE_IP_DMC),
  89        SAVE_ITEM(S5P_CLKSRC_CPU),
  90        SAVE_ITEM(S5P_CLKDIV_CPU),
  91        SAVE_ITEM(S5P_CLKDIV_CPU + 0x4),
  92        SAVE_ITEM(S5P_CLKGATE_SCLKCPU),
  93        SAVE_ITEM(S5P_CLKGATE_IP_CPU),
  94};
  95
  96struct clk clk_sclk_hdmi27m = {
  97        .name           = "sclk_hdmi27m",
  98        .rate           = 27000000,
  99};
 100
 101struct clk clk_sclk_hdmiphy = {
 102        .name           = "sclk_hdmiphy",
 103};
 104
 105struct clk clk_sclk_usbphy0 = {
 106        .name           = "sclk_usbphy0",
 107        .rate           = 27000000,
 108};
 109
 110struct clk clk_sclk_usbphy1 = {
 111        .name           = "sclk_usbphy1",
 112};
 113
 114static struct clk dummy_apb_pclk = {
 115        .name           = "apb_pclk",
 116        .id             = -1,
 117};
 118
 119static int exynos4_clksrc_mask_top_ctrl(struct clk *clk, int enable)
 120{
 121        return s5p_gatectrl(S5P_CLKSRC_MASK_TOP, clk, enable);
 122}
 123
 124static int exynos4_clksrc_mask_cam_ctrl(struct clk *clk, int enable)
 125{
 126        return s5p_gatectrl(S5P_CLKSRC_MASK_CAM, clk, enable);
 127}
 128
 129static int exynos4_clksrc_mask_lcd0_ctrl(struct clk *clk, int enable)
 130{
 131        return s5p_gatectrl(S5P_CLKSRC_MASK_LCD0, clk, enable);
 132}
 133
 134int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable)
 135{
 136        return s5p_gatectrl(S5P_CLKSRC_MASK_FSYS, clk, enable);
 137}
 138
 139static int exynos4_clksrc_mask_peril0_ctrl(struct clk *clk, int enable)
 140{
 141        return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL0, clk, enable);
 142}
 143
 144static int exynos4_clksrc_mask_peril1_ctrl(struct clk *clk, int enable)
 145{
 146        return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL1, clk, enable);
 147}
 148
 149static int exynos4_clk_ip_mfc_ctrl(struct clk *clk, int enable)
 150{
 151        return s5p_gatectrl(S5P_CLKGATE_IP_MFC, clk, enable);
 152}
 153
 154static int exynos4_clksrc_mask_tv_ctrl(struct clk *clk, int enable)
 155{
 156        return s5p_gatectrl(S5P_CLKSRC_MASK_TV, clk, enable);
 157}
 158
 159static int exynos4_clk_ip_cam_ctrl(struct clk *clk, int enable)
 160{
 161        return s5p_gatectrl(S5P_CLKGATE_IP_CAM, clk, enable);
 162}
 163
 164static int exynos4_clk_ip_tv_ctrl(struct clk *clk, int enable)
 165{
 166        return s5p_gatectrl(S5P_CLKGATE_IP_TV, clk, enable);
 167}
 168
 169static int exynos4_clk_ip_image_ctrl(struct clk *clk, int enable)
 170{
 171        return s5p_gatectrl(S5P_CLKGATE_IP_IMAGE, clk, enable);
 172}
 173
 174static int exynos4_clk_ip_lcd0_ctrl(struct clk *clk, int enable)
 175{
 176        return s5p_gatectrl(S5P_CLKGATE_IP_LCD0, clk, enable);
 177}
 178
 179int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable)
 180{
 181        return s5p_gatectrl(S5P_CLKGATE_IP_LCD1, clk, enable);
 182}
 183
 184int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable)
 185{
 186        return s5p_gatectrl(S5P_CLKGATE_IP_FSYS, clk, enable);
 187}
 188
 189static int exynos4_clk_ip_peril_ctrl(struct clk *clk, int enable)
 190{
 191        return s5p_gatectrl(S5P_CLKGATE_IP_PERIL, clk, enable);
 192}
 193
 194static int exynos4_clk_ip_perir_ctrl(struct clk *clk, int enable)
 195{
 196        return s5p_gatectrl(S5P_CLKGATE_IP_PERIR, clk, enable);
 197}
 198
 199static int exynos4_clk_hdmiphy_ctrl(struct clk *clk, int enable)
 200{
 201        return s5p_gatectrl(S5P_HDMI_PHY_CONTROL, clk, enable);
 202}
 203
 204static int exynos4_clk_dac_ctrl(struct clk *clk, int enable)
 205{
 206        return s5p_gatectrl(S5P_DAC_PHY_CONTROL, clk, enable);
 207}
 208
 209/* Core list of CMU_CPU side */
 210
 211static struct clksrc_clk clk_mout_apll = {
 212        .clk    = {
 213                .name           = "mout_apll",
 214        },
 215        .sources        = &clk_src_apll,
 216        .reg_src        = { .reg = S5P_CLKSRC_CPU, .shift = 0, .size = 1 },
 217};
 218
 219struct clksrc_clk clk_sclk_apll = {
 220        .clk    = {
 221                .name           = "sclk_apll",
 222                .parent         = &clk_mout_apll.clk,
 223        },
 224        .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 24, .size = 3 },
 225};
 226
 227struct clksrc_clk clk_mout_epll = {
 228        .clk    = {
 229                .name           = "mout_epll",
 230        },
 231        .sources        = &clk_src_epll,
 232        .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 4, .size = 1 },
 233};
 234
 235struct clksrc_clk clk_mout_mpll = {
 236        .clk = {
 237                .name           = "mout_mpll",
 238        },
 239        .sources        = &clk_src_mpll,
 240
 241        /* reg_src will be added in each SoCs' clock */
 242};
 243
 244static struct clk *clkset_moutcore_list[] = {
 245        [0] = &clk_mout_apll.clk,
 246        [1] = &clk_mout_mpll.clk,
 247};
 248
 249static struct clksrc_sources clkset_moutcore = {
 250        .sources        = clkset_moutcore_list,
 251        .nr_sources     = ARRAY_SIZE(clkset_moutcore_list),
 252};
 253
 254static struct clksrc_clk clk_moutcore = {
 255        .clk    = {
 256                .name           = "moutcore",
 257        },
 258        .sources        = &clkset_moutcore,
 259        .reg_src        = { .reg = S5P_CLKSRC_CPU, .shift = 16, .size = 1 },
 260};
 261
 262static struct clksrc_clk clk_coreclk = {
 263        .clk    = {
 264                .name           = "core_clk",
 265                .parent         = &clk_moutcore.clk,
 266        },
 267        .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 0, .size = 3 },
 268};
 269
 270static struct clksrc_clk clk_armclk = {
 271        .clk    = {
 272                .name           = "armclk",
 273                .parent         = &clk_coreclk.clk,
 274        },
 275};
 276
 277static struct clksrc_clk clk_aclk_corem0 = {
 278        .clk    = {
 279                .name           = "aclk_corem0",
 280                .parent         = &clk_coreclk.clk,
 281        },
 282        .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 4, .size = 3 },
 283};
 284
 285static struct clksrc_clk clk_aclk_cores = {
 286        .clk    = {
 287                .name           = "aclk_cores",
 288                .parent         = &clk_coreclk.clk,
 289        },
 290        .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 4, .size = 3 },
 291};
 292
 293static struct clksrc_clk clk_aclk_corem1 = {
 294        .clk    = {
 295                .name           = "aclk_corem1",
 296                .parent         = &clk_coreclk.clk,
 297        },
 298        .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 8, .size = 3 },
 299};
 300
 301static struct clksrc_clk clk_periphclk = {
 302        .clk    = {
 303                .name           = "periphclk",
 304                .parent         = &clk_coreclk.clk,
 305        },
 306        .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 12, .size = 3 },
 307};
 308
 309/* Core list of CMU_CORE side */
 310
 311struct clk *clkset_corebus_list[] = {
 312        [0] = &clk_mout_mpll.clk,
 313        [1] = &clk_sclk_apll.clk,
 314};
 315
 316struct clksrc_sources clkset_mout_corebus = {
 317        .sources        = clkset_corebus_list,
 318        .nr_sources     = ARRAY_SIZE(clkset_corebus_list),
 319};
 320
 321static struct clksrc_clk clk_mout_corebus = {
 322        .clk    = {
 323                .name           = "mout_corebus",
 324        },
 325        .sources        = &clkset_mout_corebus,
 326        .reg_src        = { .reg = S5P_CLKSRC_DMC, .shift = 4, .size = 1 },
 327};
 328
 329static struct clksrc_clk clk_sclk_dmc = {
 330        .clk    = {
 331                .name           = "sclk_dmc",
 332                .parent         = &clk_mout_corebus.clk,
 333        },
 334        .reg_div        = { .reg = S5P_CLKDIV_DMC0, .shift = 12, .size = 3 },
 335};
 336
 337static struct clksrc_clk clk_aclk_cored = {
 338        .clk    = {
 339                .name           = "aclk_cored",
 340                .parent         = &clk_sclk_dmc.clk,
 341        },
 342        .reg_div        = { .reg = S5P_CLKDIV_DMC0, .shift = 16, .size = 3 },
 343};
 344
 345static struct clksrc_clk clk_aclk_corep = {
 346        .clk    = {
 347                .name           = "aclk_corep",
 348                .parent         = &clk_aclk_cored.clk,
 349        },
 350        .reg_div        = { .reg = S5P_CLKDIV_DMC0, .shift = 20, .size = 3 },
 351};
 352
 353static struct clksrc_clk clk_aclk_acp = {
 354        .clk    = {
 355                .name           = "aclk_acp",
 356                .parent         = &clk_mout_corebus.clk,
 357        },
 358        .reg_div        = { .reg = S5P_CLKDIV_DMC0, .shift = 0, .size = 3 },
 359};
 360
 361static struct clksrc_clk clk_pclk_acp = {
 362        .clk    = {
 363                .name           = "pclk_acp",
 364                .parent         = &clk_aclk_acp.clk,
 365        },
 366        .reg_div        = { .reg = S5P_CLKDIV_DMC0, .shift = 4, .size = 3 },
 367};
 368
 369/* Core list of CMU_TOP side */
 370
 371struct clk *clkset_aclk_top_list[] = {
 372        [0] = &clk_mout_mpll.clk,
 373        [1] = &clk_sclk_apll.clk,
 374};
 375
 376struct clksrc_sources clkset_aclk = {
 377        .sources        = clkset_aclk_top_list,
 378        .nr_sources     = ARRAY_SIZE(clkset_aclk_top_list),
 379};
 380
 381static struct clksrc_clk clk_aclk_200 = {
 382        .clk    = {
 383                .name           = "aclk_200",
 384        },
 385        .sources        = &clkset_aclk,
 386        .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 12, .size = 1 },
 387        .reg_div        = { .reg = S5P_CLKDIV_TOP, .shift = 0, .size = 3 },
 388};
 389
 390static struct clksrc_clk clk_aclk_100 = {
 391        .clk    = {
 392                .name           = "aclk_100",
 393        },
 394        .sources        = &clkset_aclk,
 395        .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 16, .size = 1 },
 396        .reg_div        = { .reg = S5P_CLKDIV_TOP, .shift = 4, .size = 4 },
 397};
 398
 399static struct clksrc_clk clk_aclk_160 = {
 400        .clk    = {
 401                .name           = "aclk_160",
 402        },
 403        .sources        = &clkset_aclk,
 404        .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 20, .size = 1 },
 405        .reg_div        = { .reg = S5P_CLKDIV_TOP, .shift = 8, .size = 3 },
 406};
 407
 408struct clksrc_clk clk_aclk_133 = {
 409        .clk    = {
 410                .name           = "aclk_133",
 411        },
 412        .sources        = &clkset_aclk,
 413        .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 24, .size = 1 },
 414        .reg_div        = { .reg = S5P_CLKDIV_TOP, .shift = 12, .size = 3 },
 415};
 416
 417static struct clk *clkset_vpllsrc_list[] = {
 418        [0] = &clk_fin_vpll,
 419        [1] = &clk_sclk_hdmi27m,
 420};
 421
 422static struct clksrc_sources clkset_vpllsrc = {
 423        .sources        = clkset_vpllsrc_list,
 424        .nr_sources     = ARRAY_SIZE(clkset_vpllsrc_list),
 425};
 426
 427static struct clksrc_clk clk_vpllsrc = {
 428        .clk    = {
 429                .name           = "vpll_src",
 430                .enable         = exynos4_clksrc_mask_top_ctrl,
 431                .ctrlbit        = (1 << 0),
 432        },
 433        .sources        = &clkset_vpllsrc,
 434        .reg_src        = { .reg = S5P_CLKSRC_TOP1, .shift = 0, .size = 1 },
 435};
 436
 437static struct clk *clkset_sclk_vpll_list[] = {
 438        [0] = &clk_vpllsrc.clk,
 439        [1] = &clk_fout_vpll,
 440};
 441
 442static struct clksrc_sources clkset_sclk_vpll = {
 443        .sources        = clkset_sclk_vpll_list,
 444        .nr_sources     = ARRAY_SIZE(clkset_sclk_vpll_list),
 445};
 446
 447struct clksrc_clk clk_sclk_vpll = {
 448        .clk    = {
 449                .name           = "sclk_vpll",
 450        },
 451        .sources        = &clkset_sclk_vpll,
 452        .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 8, .size = 1 },
 453};
 454
 455static struct clk init_clocks_off[] = {
 456        {
 457                .name           = "timers",
 458                .parent         = &clk_aclk_100.clk,
 459                .enable         = exynos4_clk_ip_peril_ctrl,
 460                .ctrlbit        = (1<<24),
 461        }, {
 462                .name           = "csis",
 463                .devname        = "s5p-mipi-csis.0",
 464                .enable         = exynos4_clk_ip_cam_ctrl,
 465                .ctrlbit        = (1 << 4),
 466        }, {
 467                .name           = "csis",
 468                .devname        = "s5p-mipi-csis.1",
 469                .enable         = exynos4_clk_ip_cam_ctrl,
 470                .ctrlbit        = (1 << 5),
 471        }, {
 472                .name           = "fimc",
 473                .devname        = "exynos4-fimc.0",
 474                .enable         = exynos4_clk_ip_cam_ctrl,
 475                .ctrlbit        = (1 << 0),
 476        }, {
 477                .name           = "fimc",
 478                .devname        = "exynos4-fimc.1",
 479                .enable         = exynos4_clk_ip_cam_ctrl,
 480                .ctrlbit        = (1 << 1),
 481        }, {
 482                .name           = "fimc",
 483                .devname        = "exynos4-fimc.2",
 484                .enable         = exynos4_clk_ip_cam_ctrl,
 485                .ctrlbit        = (1 << 2),
 486        }, {
 487                .name           = "fimc",
 488                .devname        = "exynos4-fimc.3",
 489                .enable         = exynos4_clk_ip_cam_ctrl,
 490                .ctrlbit        = (1 << 3),
 491        }, {
 492                .name           = "fimd",
 493                .devname        = "exynos4-fb.0",
 494                .enable         = exynos4_clk_ip_lcd0_ctrl,
 495                .ctrlbit        = (1 << 0),
 496        }, {
 497                .name           = "hsmmc",
 498                .devname        = "s3c-sdhci.0",
 499                .parent         = &clk_aclk_133.clk,
 500                .enable         = exynos4_clk_ip_fsys_ctrl,
 501                .ctrlbit        = (1 << 5),
 502        }, {
 503                .name           = "hsmmc",
 504                .devname        = "s3c-sdhci.1",
 505                .parent         = &clk_aclk_133.clk,
 506                .enable         = exynos4_clk_ip_fsys_ctrl,
 507                .ctrlbit        = (1 << 6),
 508        }, {
 509                .name           = "hsmmc",
 510                .devname        = "s3c-sdhci.2",
 511                .parent         = &clk_aclk_133.clk,
 512                .enable         = exynos4_clk_ip_fsys_ctrl,
 513                .ctrlbit        = (1 << 7),
 514        }, {
 515                .name           = "hsmmc",
 516                .devname        = "s3c-sdhci.3",
 517                .parent         = &clk_aclk_133.clk,
 518                .enable         = exynos4_clk_ip_fsys_ctrl,
 519                .ctrlbit        = (1 << 8),
 520        }, {
 521                .name           = "dwmmc",
 522                .parent         = &clk_aclk_133.clk,
 523                .enable         = exynos4_clk_ip_fsys_ctrl,
 524                .ctrlbit        = (1 << 9),
 525        }, {
 526                .name           = "dac",
 527                .devname        = "s5p-sdo",
 528                .enable         = exynos4_clk_ip_tv_ctrl,
 529                .ctrlbit        = (1 << 2),
 530        }, {
 531                .name           = "mixer",
 532                .devname        = "s5p-mixer",
 533                .enable         = exynos4_clk_ip_tv_ctrl,
 534                .ctrlbit        = (1 << 1),
 535        }, {
 536                .name           = "vp",
 537                .devname        = "s5p-mixer",
 538                .enable         = exynos4_clk_ip_tv_ctrl,
 539                .ctrlbit        = (1 << 0),
 540        }, {
 541                .name           = "hdmi",
 542                .devname        = "exynos4-hdmi",
 543                .enable         = exynos4_clk_ip_tv_ctrl,
 544                .ctrlbit        = (1 << 3),
 545        }, {
 546                .name           = "hdmiphy",
 547                .devname        = "exynos4-hdmi",
 548                .enable         = exynos4_clk_hdmiphy_ctrl,
 549                .ctrlbit        = (1 << 0),
 550        }, {
 551                .name           = "dacphy",
 552                .devname        = "s5p-sdo",
 553                .enable         = exynos4_clk_dac_ctrl,
 554                .ctrlbit        = (1 << 0),
 555        }, {
 556                .name           = "dma",
 557                .devname        = "dma-pl330.0",
 558                .enable         = exynos4_clk_ip_fsys_ctrl,
 559                .ctrlbit        = (1 << 0),
 560        }, {
 561                .name           = "dma",
 562                .devname        = "dma-pl330.1",
 563                .enable         = exynos4_clk_ip_fsys_ctrl,
 564                .ctrlbit        = (1 << 1),
 565        }, {
 566                .name           = "adc",
 567                .enable         = exynos4_clk_ip_peril_ctrl,
 568                .ctrlbit        = (1 << 15),
 569        }, {
 570                .name           = "keypad",
 571                .enable         = exynos4_clk_ip_perir_ctrl,
 572                .ctrlbit        = (1 << 16),
 573        }, {
 574                .name           = "rtc",
 575                .enable         = exynos4_clk_ip_perir_ctrl,
 576                .ctrlbit        = (1 << 15),
 577        }, {
 578                .name           = "watchdog",
 579                .parent         = &clk_aclk_100.clk,
 580                .enable         = exynos4_clk_ip_perir_ctrl,
 581                .ctrlbit        = (1 << 14),
 582        }, {
 583                .name           = "usbhost",
 584                .enable         = exynos4_clk_ip_fsys_ctrl ,
 585                .ctrlbit        = (1 << 12),
 586        }, {
 587                .name           = "otg",
 588                .enable         = exynos4_clk_ip_fsys_ctrl,
 589                .ctrlbit        = (1 << 13),
 590        }, {
 591                .name           = "spi",
 592                .devname        = "s3c64xx-spi.0",
 593                .enable         = exynos4_clk_ip_peril_ctrl,
 594                .ctrlbit        = (1 << 16),
 595        }, {
 596                .name           = "spi",
 597                .devname        = "s3c64xx-spi.1",
 598                .enable         = exynos4_clk_ip_peril_ctrl,
 599                .ctrlbit        = (1 << 17),
 600        }, {
 601                .name           = "spi",
 602                .devname        = "s3c64xx-spi.2",
 603                .enable         = exynos4_clk_ip_peril_ctrl,
 604                .ctrlbit        = (1 << 18),
 605        }, {
 606                .name           = "iis",
 607                .devname        = "samsung-i2s.0",
 608                .enable         = exynos4_clk_ip_peril_ctrl,
 609                .ctrlbit        = (1 << 19),
 610        }, {
 611                .name           = "iis",
 612                .devname        = "samsung-i2s.1",
 613                .enable         = exynos4_clk_ip_peril_ctrl,
 614                .ctrlbit        = (1 << 20),
 615        }, {
 616                .name           = "iis",
 617                .devname        = "samsung-i2s.2",
 618                .enable         = exynos4_clk_ip_peril_ctrl,
 619                .ctrlbit        = (1 << 21),
 620        }, {
 621                .name           = "ac97",
 622                .devname        = "samsung-ac97",
 623                .enable         = exynos4_clk_ip_peril_ctrl,
 624                .ctrlbit        = (1 << 27),
 625        }, {
 626                .name           = "fimg2d",
 627                .enable         = exynos4_clk_ip_image_ctrl,
 628                .ctrlbit        = (1 << 0),
 629        }, {
 630                .name           = "mfc",
 631                .devname        = "s5p-mfc",
 632                .enable         = exynos4_clk_ip_mfc_ctrl,
 633                .ctrlbit        = (1 << 0),
 634        }, {
 635                .name           = "i2c",
 636                .devname        = "s3c2440-i2c.0",
 637                .parent         = &clk_aclk_100.clk,
 638                .enable         = exynos4_clk_ip_peril_ctrl,
 639                .ctrlbit        = (1 << 6),
 640        }, {
 641                .name           = "i2c",
 642                .devname        = "s3c2440-i2c.1",
 643                .parent         = &clk_aclk_100.clk,
 644                .enable         = exynos4_clk_ip_peril_ctrl,
 645                .ctrlbit        = (1 << 7),
 646        }, {
 647                .name           = "i2c",
 648                .devname        = "s3c2440-i2c.2",
 649                .parent         = &clk_aclk_100.clk,
 650                .enable         = exynos4_clk_ip_peril_ctrl,
 651                .ctrlbit        = (1 << 8),
 652        }, {
 653                .name           = "i2c",
 654                .devname        = "s3c2440-i2c.3",
 655                .parent         = &clk_aclk_100.clk,
 656                .enable         = exynos4_clk_ip_peril_ctrl,
 657                .ctrlbit        = (1 << 9),
 658        }, {
 659                .name           = "i2c",
 660                .devname        = "s3c2440-i2c.4",
 661                .parent         = &clk_aclk_100.clk,
 662                .enable         = exynos4_clk_ip_peril_ctrl,
 663                .ctrlbit        = (1 << 10),
 664        }, {
 665                .name           = "i2c",
 666                .devname        = "s3c2440-i2c.5",
 667                .parent         = &clk_aclk_100.clk,
 668                .enable         = exynos4_clk_ip_peril_ctrl,
 669                .ctrlbit        = (1 << 11),
 670        }, {
 671                .name           = "i2c",
 672                .devname        = "s3c2440-i2c.6",
 673                .parent         = &clk_aclk_100.clk,
 674                .enable         = exynos4_clk_ip_peril_ctrl,
 675                .ctrlbit        = (1 << 12),
 676        }, {
 677                .name           = "i2c",
 678                .devname        = "s3c2440-i2c.7",
 679                .parent         = &clk_aclk_100.clk,
 680                .enable         = exynos4_clk_ip_peril_ctrl,
 681                .ctrlbit        = (1 << 13),
 682        }, {
 683                .name           = "i2c",
 684                .devname        = "s3c2440-hdmiphy-i2c",
 685                .parent         = &clk_aclk_100.clk,
 686                .enable         = exynos4_clk_ip_peril_ctrl,
 687                .ctrlbit        = (1 << 14),
 688        }, {
 689                .name           = "SYSMMU_MDMA",
 690                .enable         = exynos4_clk_ip_image_ctrl,
 691                .ctrlbit        = (1 << 5),
 692        }, {
 693                .name           = "SYSMMU_FIMC0",
 694                .enable         = exynos4_clk_ip_cam_ctrl,
 695                .ctrlbit        = (1 << 7),
 696        }, {
 697                .name           = "SYSMMU_FIMC1",
 698                .enable         = exynos4_clk_ip_cam_ctrl,
 699                .ctrlbit        = (1 << 8),
 700        }, {
 701                .name           = "SYSMMU_FIMC2",
 702                .enable         = exynos4_clk_ip_cam_ctrl,
 703                .ctrlbit        = (1 << 9),
 704        }, {
 705                .name           = "SYSMMU_FIMC3",
 706                .enable         = exynos4_clk_ip_cam_ctrl,
 707                .ctrlbit        = (1 << 10),
 708        }, {
 709                .name           = "SYSMMU_JPEG",
 710                .enable         = exynos4_clk_ip_cam_ctrl,
 711                .ctrlbit        = (1 << 11),
 712        }, {
 713                .name           = "SYSMMU_FIMD0",
 714                .enable         = exynos4_clk_ip_lcd0_ctrl,
 715                .ctrlbit        = (1 << 4),
 716        }, {
 717                .name           = "SYSMMU_FIMD1",
 718                .enable         = exynos4_clk_ip_lcd1_ctrl,
 719                .ctrlbit        = (1 << 4),
 720        }, {
 721                .name           = "SYSMMU_PCIe",
 722                .enable         = exynos4_clk_ip_fsys_ctrl,
 723                .ctrlbit        = (1 << 18),
 724        }, {
 725                .name           = "SYSMMU_G2D",
 726                .enable         = exynos4_clk_ip_image_ctrl,
 727                .ctrlbit        = (1 << 3),
 728        }, {
 729                .name           = "SYSMMU_ROTATOR",
 730                .enable         = exynos4_clk_ip_image_ctrl,
 731                .ctrlbit        = (1 << 4),
 732        }, {
 733                .name           = "SYSMMU_TV",
 734                .enable         = exynos4_clk_ip_tv_ctrl,
 735                .ctrlbit        = (1 << 4),
 736        }, {
 737                .name           = "SYSMMU_MFC_L",
 738                .enable         = exynos4_clk_ip_mfc_ctrl,
 739                .ctrlbit        = (1 << 1),
 740        }, {
 741                .name           = "SYSMMU_MFC_R",
 742                .enable         = exynos4_clk_ip_mfc_ctrl,
 743                .ctrlbit        = (1 << 2),
 744        }
 745};
 746
 747static struct clk init_clocks[] = {
 748        {
 749                .name           = "uart",
 750                .devname        = "s5pv210-uart.0",
 751                .enable         = exynos4_clk_ip_peril_ctrl,
 752                .ctrlbit        = (1 << 0),
 753        }, {
 754                .name           = "uart",
 755                .devname        = "s5pv210-uart.1",
 756                .enable         = exynos4_clk_ip_peril_ctrl,
 757                .ctrlbit        = (1 << 1),
 758        }, {
 759                .name           = "uart",
 760                .devname        = "s5pv210-uart.2",
 761                .enable         = exynos4_clk_ip_peril_ctrl,
 762                .ctrlbit        = (1 << 2),
 763        }, {
 764                .name           = "uart",
 765                .devname        = "s5pv210-uart.3",
 766                .enable         = exynos4_clk_ip_peril_ctrl,
 767                .ctrlbit        = (1 << 3),
 768        }, {
 769                .name           = "uart",
 770                .devname        = "s5pv210-uart.4",
 771                .enable         = exynos4_clk_ip_peril_ctrl,
 772                .ctrlbit        = (1 << 4),
 773        }, {
 774                .name           = "uart",
 775                .devname        = "s5pv210-uart.5",
 776                .enable         = exynos4_clk_ip_peril_ctrl,
 777                .ctrlbit        = (1 << 5),
 778        }
 779};
 780
 781struct clk *clkset_group_list[] = {
 782        [0] = &clk_ext_xtal_mux,
 783        [1] = &clk_xusbxti,
 784        [2] = &clk_sclk_hdmi27m,
 785        [3] = &clk_sclk_usbphy0,
 786        [4] = &clk_sclk_usbphy1,
 787        [5] = &clk_sclk_hdmiphy,
 788        [6] = &clk_mout_mpll.clk,
 789        [7] = &clk_mout_epll.clk,
 790        [8] = &clk_sclk_vpll.clk,
 791};
 792
 793struct clksrc_sources clkset_group = {
 794        .sources        = clkset_group_list,
 795        .nr_sources     = ARRAY_SIZE(clkset_group_list),
 796};
 797
 798static struct clk *clkset_mout_g2d0_list[] = {
 799        [0] = &clk_mout_mpll.clk,
 800        [1] = &clk_sclk_apll.clk,
 801};
 802
 803static struct clksrc_sources clkset_mout_g2d0 = {
 804        .sources        = clkset_mout_g2d0_list,
 805        .nr_sources     = ARRAY_SIZE(clkset_mout_g2d0_list),
 806};
 807
 808static struct clksrc_clk clk_mout_g2d0 = {
 809        .clk    = {
 810                .name           = "mout_g2d0",
 811        },
 812        .sources        = &clkset_mout_g2d0,
 813        .reg_src        = { .reg = S5P_CLKSRC_IMAGE, .shift = 0, .size = 1 },
 814};
 815
 816static struct clk *clkset_mout_g2d1_list[] = {
 817        [0] = &clk_mout_epll.clk,
 818        [1] = &clk_sclk_vpll.clk,
 819};
 820
 821static struct clksrc_sources clkset_mout_g2d1 = {
 822        .sources        = clkset_mout_g2d1_list,
 823        .nr_sources     = ARRAY_SIZE(clkset_mout_g2d1_list),
 824};
 825
 826static struct clksrc_clk clk_mout_g2d1 = {
 827        .clk    = {
 828                .name           = "mout_g2d1",
 829        },
 830        .sources        = &clkset_mout_g2d1,
 831        .reg_src        = { .reg = S5P_CLKSRC_IMAGE, .shift = 4, .size = 1 },
 832};
 833
 834static struct clk *clkset_mout_g2d_list[] = {
 835        [0] = &clk_mout_g2d0.clk,
 836        [1] = &clk_mout_g2d1.clk,
 837};
 838
 839static struct clksrc_sources clkset_mout_g2d = {
 840        .sources        = clkset_mout_g2d_list,
 841        .nr_sources     = ARRAY_SIZE(clkset_mout_g2d_list),
 842};
 843
 844static struct clk *clkset_mout_mfc0_list[] = {
 845        [0] = &clk_mout_mpll.clk,
 846        [1] = &clk_sclk_apll.clk,
 847};
 848
 849static struct clksrc_sources clkset_mout_mfc0 = {
 850        .sources        = clkset_mout_mfc0_list,
 851        .nr_sources     = ARRAY_SIZE(clkset_mout_mfc0_list),
 852};
 853
 854static struct clksrc_clk clk_mout_mfc0 = {
 855        .clk    = {
 856                .name           = "mout_mfc0",
 857        },
 858        .sources        = &clkset_mout_mfc0,
 859        .reg_src        = { .reg = S5P_CLKSRC_MFC, .shift = 0, .size = 1 },
 860};
 861
 862static struct clk *clkset_mout_mfc1_list[] = {
 863        [0] = &clk_mout_epll.clk,
 864        [1] = &clk_sclk_vpll.clk,
 865};
 866
 867static struct clksrc_sources clkset_mout_mfc1 = {
 868        .sources        = clkset_mout_mfc1_list,
 869        .nr_sources     = ARRAY_SIZE(clkset_mout_mfc1_list),
 870};
 871
 872static struct clksrc_clk clk_mout_mfc1 = {
 873        .clk    = {
 874                .name           = "mout_mfc1",
 875        },
 876        .sources        = &clkset_mout_mfc1,
 877        .reg_src        = { .reg = S5P_CLKSRC_MFC, .shift = 4, .size = 1 },
 878};
 879
 880static struct clk *clkset_mout_mfc_list[] = {
 881        [0] = &clk_mout_mfc0.clk,
 882        [1] = &clk_mout_mfc1.clk,
 883};
 884
 885static struct clksrc_sources clkset_mout_mfc = {
 886        .sources        = clkset_mout_mfc_list,
 887        .nr_sources     = ARRAY_SIZE(clkset_mout_mfc_list),
 888};
 889
 890static struct clk *clkset_sclk_dac_list[] = {
 891        [0] = &clk_sclk_vpll.clk,
 892        [1] = &clk_sclk_hdmiphy,
 893};
 894
 895static struct clksrc_sources clkset_sclk_dac = {
 896        .sources        = clkset_sclk_dac_list,
 897        .nr_sources     = ARRAY_SIZE(clkset_sclk_dac_list),
 898};
 899
 900static struct clksrc_clk clk_sclk_dac = {
 901        .clk            = {
 902                .name           = "sclk_dac",
 903                .enable         = exynos4_clksrc_mask_tv_ctrl,
 904                .ctrlbit        = (1 << 8),
 905        },
 906        .sources = &clkset_sclk_dac,
 907        .reg_src = { .reg = S5P_CLKSRC_TV, .shift = 8, .size = 1 },
 908};
 909
 910static struct clksrc_clk clk_sclk_pixel = {
 911        .clk            = {
 912                .name           = "sclk_pixel",
 913                .parent = &clk_sclk_vpll.clk,
 914        },
 915        .reg_div = { .reg = S5P_CLKDIV_TV, .shift = 0, .size = 4 },
 916};
 917
 918static struct clk *clkset_sclk_hdmi_list[] = {
 919        [0] = &clk_sclk_pixel.clk,
 920        [1] = &clk_sclk_hdmiphy,
 921};
 922
 923static struct clksrc_sources clkset_sclk_hdmi = {
 924        .sources        = clkset_sclk_hdmi_list,
 925        .nr_sources     = ARRAY_SIZE(clkset_sclk_hdmi_list),
 926};
 927
 928static struct clksrc_clk clk_sclk_hdmi = {
 929        .clk            = {
 930                .name           = "sclk_hdmi",
 931                .enable         = exynos4_clksrc_mask_tv_ctrl,
 932                .ctrlbit        = (1 << 0),
 933        },
 934        .sources = &clkset_sclk_hdmi,
 935        .reg_src = { .reg = S5P_CLKSRC_TV, .shift = 0, .size = 1 },
 936};
 937
 938static struct clk *clkset_sclk_mixer_list[] = {
 939        [0] = &clk_sclk_dac.clk,
 940        [1] = &clk_sclk_hdmi.clk,
 941};
 942
 943static struct clksrc_sources clkset_sclk_mixer = {
 944        .sources        = clkset_sclk_mixer_list,
 945        .nr_sources     = ARRAY_SIZE(clkset_sclk_mixer_list),
 946};
 947
 948static struct clksrc_clk clk_sclk_mixer = {
 949        .clk            = {
 950                .name           = "sclk_mixer",
 951                .enable         = exynos4_clksrc_mask_tv_ctrl,
 952                .ctrlbit        = (1 << 4),
 953        },
 954        .sources = &clkset_sclk_mixer,
 955        .reg_src = { .reg = S5P_CLKSRC_TV, .shift = 4, .size = 1 },
 956};
 957
 958static struct clksrc_clk *sclk_tv[] = {
 959        &clk_sclk_dac,
 960        &clk_sclk_pixel,
 961        &clk_sclk_hdmi,
 962        &clk_sclk_mixer,
 963};
 964
 965static struct clksrc_clk clk_dout_mmc0 = {
 966        .clk            = {
 967                .name           = "dout_mmc0",
 968        },
 969        .sources = &clkset_group,
 970        .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 0, .size = 4 },
 971        .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 0, .size = 4 },
 972};
 973
 974static struct clksrc_clk clk_dout_mmc1 = {
 975        .clk            = {
 976                .name           = "dout_mmc1",
 977        },
 978        .sources = &clkset_group,
 979        .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 4, .size = 4 },
 980        .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 16, .size = 4 },
 981};
 982
 983static struct clksrc_clk clk_dout_mmc2 = {
 984        .clk            = {
 985                .name           = "dout_mmc2",
 986        },
 987        .sources = &clkset_group,
 988        .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 8, .size = 4 },
 989        .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 0, .size = 4 },
 990};
 991
 992static struct clksrc_clk clk_dout_mmc3 = {
 993        .clk            = {
 994                .name           = "dout_mmc3",
 995        },
 996        .sources = &clkset_group,
 997        .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 12, .size = 4 },
 998        .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 16, .size = 4 },
 999};
1000
1001static struct clksrc_clk clk_dout_mmc4 = {
1002        .clk            = {
1003                .name           = "dout_mmc4",
1004        },
1005        .sources = &clkset_group,
1006        .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 16, .size = 4 },
1007        .reg_div = { .reg = S5P_CLKDIV_FSYS3, .shift = 0, .size = 4 },
1008};
1009
1010static struct clksrc_clk clksrcs[] = {
1011        {
1012                .clk    = {
1013                        .name           = "uclk1",
1014                        .devname        = "s5pv210-uart.0",
1015                        .enable         = exynos4_clksrc_mask_peril0_ctrl,
1016                        .ctrlbit        = (1 << 0),
1017                },
1018                .sources = &clkset_group,
1019                .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 0, .size = 4 },
1020                .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 0, .size = 4 },
1021        }, {
1022                .clk            = {
1023                        .name           = "uclk1",
1024                        .devname        = "s5pv210-uart.1",
1025                        .enable         = exynos4_clksrc_mask_peril0_ctrl,
1026                        .ctrlbit        = (1 << 4),
1027                },
1028                .sources = &clkset_group,
1029                .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 4, .size = 4 },
1030                .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 4, .size = 4 },
1031        }, {
1032                .clk            = {
1033                        .name           = "uclk1",
1034                        .devname        = "s5pv210-uart.2",
1035                        .enable         = exynos4_clksrc_mask_peril0_ctrl,
1036                        .ctrlbit        = (1 << 8),
1037                },
1038                .sources = &clkset_group,
1039                .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 8, .size = 4 },
1040                .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 8, .size = 4 },
1041        }, {
1042                .clk            = {
1043                        .name           = "uclk1",
1044                        .devname        = "s5pv210-uart.3",
1045                        .enable         = exynos4_clksrc_mask_peril0_ctrl,
1046                        .ctrlbit        = (1 << 12),
1047                },
1048                .sources = &clkset_group,
1049                .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 12, .size = 4 },
1050                .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 12, .size = 4 },
1051        }, {
1052                .clk            = {
1053                        .name           = "sclk_pwm",
1054                        .enable         = exynos4_clksrc_mask_peril0_ctrl,
1055                        .ctrlbit        = (1 << 24),
1056                },
1057                .sources = &clkset_group,
1058                .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 24, .size = 4 },
1059                .reg_div = { .reg = S5P_CLKDIV_PERIL3, .shift = 0, .size = 4 },
1060        }, {
1061                .clk            = {
1062                        .name           = "sclk_csis",
1063                        .devname        = "s5p-mipi-csis.0",
1064                        .enable         = exynos4_clksrc_mask_cam_ctrl,
1065                        .ctrlbit        = (1 << 24),
1066                },
1067                .sources = &clkset_group,
1068                .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 24, .size = 4 },
1069                .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 24, .size = 4 },
1070        }, {
1071                .clk            = {
1072                        .name           = "sclk_csis",
1073                        .devname        = "s5p-mipi-csis.1",
1074                        .enable         = exynos4_clksrc_mask_cam_ctrl,
1075                        .ctrlbit        = (1 << 28),
1076                },
1077                .sources = &clkset_group,
1078                .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 28, .size = 4 },
1079                .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 28, .size = 4 },
1080        }, {
1081                .clk            = {
1082                        .name           = "sclk_cam0",
1083                        .enable         = exynos4_clksrc_mask_cam_ctrl,
1084                        .ctrlbit        = (1 << 16),
1085                },
1086                .sources = &clkset_group,
1087                .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 16, .size = 4 },
1088                .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 16, .size = 4 },
1089        }, {
1090                .clk            = {
1091                        .name           = "sclk_cam1",
1092                        .enable         = exynos4_clksrc_mask_cam_ctrl,
1093                        .ctrlbit        = (1 << 20),
1094                },
1095                .sources = &clkset_group,
1096                .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 20, .size = 4 },
1097                .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 20, .size = 4 },
1098        }, {
1099                .clk            = {
1100                        .name           = "sclk_fimc",
1101                        .devname        = "exynos4-fimc.0",
1102                        .enable         = exynos4_clksrc_mask_cam_ctrl,
1103                        .ctrlbit        = (1 << 0),
1104                },
1105                .sources = &clkset_group,
1106                .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 0, .size = 4 },
1107                .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 0, .size = 4 },
1108        }, {
1109                .clk            = {
1110                        .name           = "sclk_fimc",
1111                        .devname        = "exynos4-fimc.1",
1112                        .enable         = exynos4_clksrc_mask_cam_ctrl,
1113                        .ctrlbit        = (1 << 4),
1114                },
1115                .sources = &clkset_group,
1116                .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 4, .size = 4 },
1117                .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 4, .size = 4 },
1118        }, {
1119                .clk            = {
1120                        .name           = "sclk_fimc",
1121                        .devname        = "exynos4-fimc.2",
1122                        .enable         = exynos4_clksrc_mask_cam_ctrl,
1123                        .ctrlbit        = (1 << 8),
1124                },
1125                .sources = &clkset_group,
1126                .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 8, .size = 4 },
1127                .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 8, .size = 4 },
1128        }, {
1129                .clk            = {
1130                        .name           = "sclk_fimc",
1131                        .devname        = "exynos4-fimc.3",
1132                        .enable         = exynos4_clksrc_mask_cam_ctrl,
1133                        .ctrlbit        = (1 << 12),
1134                },
1135                .sources = &clkset_group,
1136                .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 12, .size = 4 },
1137                .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 12, .size = 4 },
1138        }, {
1139                .clk            = {
1140                        .name           = "sclk_fimd",
1141                        .devname        = "exynos4-fb.0",
1142                        .enable         = exynos4_clksrc_mask_lcd0_ctrl,
1143                        .ctrlbit        = (1 << 0),
1144                },
1145                .sources = &clkset_group,
1146                .reg_src = { .reg = S5P_CLKSRC_LCD0, .shift = 0, .size = 4 },
1147                .reg_div = { .reg = S5P_CLKDIV_LCD0, .shift = 0, .size = 4 },
1148        }, {
1149                .clk            = {
1150                        .name           = "sclk_spi",
1151                        .devname        = "s3c64xx-spi.0",
1152                        .enable         = exynos4_clksrc_mask_peril1_ctrl,
1153                        .ctrlbit        = (1 << 16),
1154                },
1155                .sources = &clkset_group,
1156                .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 16, .size = 4 },
1157                .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 0, .size = 4 },
1158        }, {
1159                .clk            = {
1160                        .name           = "sclk_spi",
1161                        .devname        = "s3c64xx-spi.1",
1162                        .enable         = exynos4_clksrc_mask_peril1_ctrl,
1163                        .ctrlbit        = (1 << 20),
1164                },
1165                .sources = &clkset_group,
1166                .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 20, .size = 4 },
1167                .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 16, .size = 4 },
1168        }, {
1169                .clk            = {
1170                        .name           = "sclk_spi",
1171                        .devname        = "s3c64xx-spi.2",
1172                        .enable         = exynos4_clksrc_mask_peril1_ctrl,
1173                        .ctrlbit        = (1 << 24),
1174                },
1175                .sources = &clkset_group,
1176                .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 24, .size = 4 },
1177                .reg_div = { .reg = S5P_CLKDIV_PERIL2, .shift = 0, .size = 4 },
1178        }, {
1179                .clk            = {
1180                        .name           = "sclk_fimg2d",
1181                },
1182                .sources = &clkset_mout_g2d,
1183                .reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 8, .size = 1 },
1184                .reg_div = { .reg = S5P_CLKDIV_IMAGE, .shift = 0, .size = 4 },
1185        }, {
1186                .clk            = {
1187                        .name           = "sclk_mfc",
1188                        .devname        = "s5p-mfc",
1189                },
1190                .sources = &clkset_mout_mfc,
1191                .reg_src = { .reg = S5P_CLKSRC_MFC, .shift = 8, .size = 1 },
1192                .reg_div = { .reg = S5P_CLKDIV_MFC, .shift = 0, .size = 4 },
1193        }, {
1194                .clk            = {
1195                        .name           = "sclk_mmc",
1196                        .devname        = "s3c-sdhci.0",
1197                        .parent         = &clk_dout_mmc0.clk,
1198                        .enable         = exynos4_clksrc_mask_fsys_ctrl,
1199                        .ctrlbit        = (1 << 0),
1200                },
1201                .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 8, .size = 8 },
1202        }, {
1203                .clk            = {
1204                        .name           = "sclk_mmc",
1205                        .devname        = "s3c-sdhci.1",
1206                        .parent         = &clk_dout_mmc1.clk,
1207                        .enable         = exynos4_clksrc_mask_fsys_ctrl,
1208                        .ctrlbit        = (1 << 4),
1209                },
1210                .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 24, .size = 8 },
1211        }, {
1212                .clk            = {
1213                        .name           = "sclk_mmc",
1214                        .devname        = "s3c-sdhci.2",
1215                        .parent         = &clk_dout_mmc2.clk,
1216                        .enable         = exynos4_clksrc_mask_fsys_ctrl,
1217                        .ctrlbit        = (1 << 8),
1218                },
1219                .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 8, .size = 8 },
1220        }, {
1221                .clk            = {
1222                        .name           = "sclk_mmc",
1223                        .devname        = "s3c-sdhci.3",
1224                        .parent         = &clk_dout_mmc3.clk,
1225                        .enable         = exynos4_clksrc_mask_fsys_ctrl,
1226                        .ctrlbit        = (1 << 12),
1227                },
1228                .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 24, .size = 8 },
1229        }, {
1230                .clk            = {
1231                        .name           = "sclk_dwmmc",
1232                        .parent         = &clk_dout_mmc4.clk,
1233                        .enable         = exynos4_clksrc_mask_fsys_ctrl,
1234                        .ctrlbit        = (1 << 16),
1235                },
1236                .reg_div = { .reg = S5P_CLKDIV_FSYS3, .shift = 8, .size = 8 },
1237        }
1238};
1239
1240/* Clock initialization code */
1241static struct clksrc_clk *sysclks[] = {
1242        &clk_mout_apll,
1243        &clk_sclk_apll,
1244        &clk_mout_epll,
1245        &clk_mout_mpll,
1246        &clk_moutcore,
1247        &clk_coreclk,
1248        &clk_armclk,
1249        &clk_aclk_corem0,
1250        &clk_aclk_cores,
1251        &clk_aclk_corem1,
1252        &clk_periphclk,
1253        &clk_mout_corebus,
1254        &clk_sclk_dmc,
1255        &clk_aclk_cored,
1256        &clk_aclk_corep,
1257        &clk_aclk_acp,
1258        &clk_pclk_acp,
1259        &clk_vpllsrc,
1260        &clk_sclk_vpll,
1261        &clk_aclk_200,
1262        &clk_aclk_100,
1263        &clk_aclk_160,
1264        &clk_aclk_133,
1265        &clk_dout_mmc0,
1266        &clk_dout_mmc1,
1267        &clk_dout_mmc2,
1268        &clk_dout_mmc3,
1269        &clk_dout_mmc4,
1270        &clk_mout_mfc0,
1271        &clk_mout_mfc1,
1272};
1273
1274static int xtal_rate;
1275
1276static unsigned long exynos4_fout_apll_get_rate(struct clk *clk)
1277{
1278        if (soc_is_exynos4210())
1279                return s5p_get_pll45xx(xtal_rate, __raw_readl(S5P_APLL_CON0),
1280                                        pll_4508);
1281        else if (soc_is_exynos4212() || soc_is_exynos4412())
1282                return s5p_get_pll35xx(xtal_rate, __raw_readl(S5P_APLL_CON0));
1283        else
1284                return 0;
1285}
1286
1287static struct clk_ops exynos4_fout_apll_ops = {
1288        .get_rate = exynos4_fout_apll_get_rate,
1289};
1290
1291static u32 vpll_div[][8] = {
1292        {  54000000, 3, 53, 3, 1024, 0, 17, 0 },
1293        { 108000000, 3, 53, 2, 1024, 0, 17, 0 },
1294};
1295
1296static unsigned long exynos4_vpll_get_rate(struct clk *clk)
1297{
1298        return clk->rate;
1299}
1300
1301static int exynos4_vpll_set_rate(struct clk *clk, unsigned long rate)
1302{
1303        unsigned int vpll_con0, vpll_con1 = 0;
1304        unsigned int i;
1305
1306        /* Return if nothing changed */
1307        if (clk->rate == rate)
1308                return 0;
1309
1310        vpll_con0 = __raw_readl(S5P_VPLL_CON0);
1311        vpll_con0 &= ~(0x1 << 27 |                                      \
1312                        PLL90XX_MDIV_MASK << PLL46XX_MDIV_SHIFT |       \
1313                        PLL90XX_PDIV_MASK << PLL46XX_PDIV_SHIFT |       \
1314                        PLL90XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
1315
1316        vpll_con1 = __raw_readl(S5P_VPLL_CON1);
1317        vpll_con1 &= ~(PLL46XX_MRR_MASK << PLL46XX_MRR_SHIFT |  \
1318                        PLL46XX_MFR_MASK << PLL46XX_MFR_SHIFT | \
1319                        PLL4650C_KDIV_MASK << PLL46XX_KDIV_SHIFT);
1320
1321        for (i = 0; i < ARRAY_SIZE(vpll_div); i++) {
1322                if (vpll_div[i][0] == rate) {
1323                        vpll_con0 |= vpll_div[i][1] << PLL46XX_PDIV_SHIFT;
1324                        vpll_con0 |= vpll_div[i][2] << PLL46XX_MDIV_SHIFT;
1325                        vpll_con0 |= vpll_div[i][3] << PLL46XX_SDIV_SHIFT;
1326                        vpll_con1 |= vpll_div[i][4] << PLL46XX_KDIV_SHIFT;
1327                        vpll_con1 |= vpll_div[i][5] << PLL46XX_MFR_SHIFT;
1328                        vpll_con1 |= vpll_div[i][6] << PLL46XX_MRR_SHIFT;
1329                        vpll_con0 |= vpll_div[i][7] << 27;
1330                        break;
1331                }
1332        }
1333
1334        if (i == ARRAY_SIZE(vpll_div)) {
1335                printk(KERN_ERR "%s: Invalid Clock VPLL Frequency\n",
1336                                __func__);
1337                return -EINVAL;
1338        }
1339
1340        __raw_writel(vpll_con0, S5P_VPLL_CON0);
1341        __raw_writel(vpll_con1, S5P_VPLL_CON1);
1342
1343        /* Wait for VPLL lock */
1344        while (!(__raw_readl(S5P_VPLL_CON0) & (1 << PLL46XX_LOCKED_SHIFT)))
1345                continue;
1346
1347        clk->rate = rate;
1348        return 0;
1349}
1350
1351static struct clk_ops exynos4_vpll_ops = {
1352        .get_rate = exynos4_vpll_get_rate,
1353        .set_rate = exynos4_vpll_set_rate,
1354};
1355
1356void __init_or_cpufreq exynos4_setup_clocks(void)
1357{
1358        struct clk *xtal_clk;
1359        unsigned long apll = 0;
1360        unsigned long mpll = 0;
1361        unsigned long epll = 0;
1362        unsigned long vpll = 0;
1363        unsigned long vpllsrc;
1364        unsigned long xtal;
1365        unsigned long armclk;
1366        unsigned long sclk_dmc;
1367        unsigned long aclk_200;
1368        unsigned long aclk_100;
1369        unsigned long aclk_160;
1370        unsigned long aclk_133;
1371        unsigned int ptr;
1372
1373        printk(KERN_DEBUG "%s: registering clocks\n", __func__);
1374
1375        xtal_clk = clk_get(NULL, "xtal");
1376        BUG_ON(IS_ERR(xtal_clk));
1377
1378        xtal = clk_get_rate(xtal_clk);
1379
1380        xtal_rate = xtal;
1381
1382        clk_put(xtal_clk);
1383
1384        printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
1385
1386        if (soc_is_exynos4210()) {
1387                apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON0),
1388                                        pll_4508);
1389                mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON0),
1390                                        pll_4508);
1391                epll = s5p_get_pll46xx(xtal, __raw_readl(S5P_EPLL_CON0),
1392                                        __raw_readl(S5P_EPLL_CON1), pll_4600);
1393
1394                vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
1395                vpll = s5p_get_pll46xx(vpllsrc, __raw_readl(S5P_VPLL_CON0),
1396                                        __raw_readl(S5P_VPLL_CON1), pll_4650c);
1397        } else if (soc_is_exynos4212() || soc_is_exynos4412()) {
1398                apll = s5p_get_pll35xx(xtal, __raw_readl(S5P_APLL_CON0));
1399                mpll = s5p_get_pll35xx(xtal, __raw_readl(S5P_MPLL_CON0));
1400                epll = s5p_get_pll36xx(xtal, __raw_readl(S5P_EPLL_CON0),
1401                                        __raw_readl(S5P_EPLL_CON1));
1402
1403                vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
1404                vpll = s5p_get_pll36xx(vpllsrc, __raw_readl(S5P_VPLL_CON0),
1405                                        __raw_readl(S5P_VPLL_CON1));
1406        } else {
1407                /* nothing */
1408        }
1409
1410        clk_fout_apll.ops = &exynos4_fout_apll_ops;
1411        clk_fout_mpll.rate = mpll;
1412        clk_fout_epll.rate = epll;
1413        clk_fout_vpll.ops = &exynos4_vpll_ops;
1414        clk_fout_vpll.rate = vpll;
1415
1416        printk(KERN_INFO "EXYNOS4: PLL settings, A=%ld, M=%ld, E=%ld V=%ld",
1417                        apll, mpll, epll, vpll);
1418
1419        armclk = clk_get_rate(&clk_armclk.clk);
1420        sclk_dmc = clk_get_rate(&clk_sclk_dmc.clk);
1421
1422        aclk_200 = clk_get_rate(&clk_aclk_200.clk);
1423        aclk_100 = clk_get_rate(&clk_aclk_100.clk);
1424        aclk_160 = clk_get_rate(&clk_aclk_160.clk);
1425        aclk_133 = clk_get_rate(&clk_aclk_133.clk);
1426
1427        printk(KERN_INFO "EXYNOS4: ARMCLK=%ld, DMC=%ld, ACLK200=%ld\n"
1428                         "ACLK100=%ld, ACLK160=%ld, ACLK133=%ld\n",
1429                        armclk, sclk_dmc, aclk_200,
1430                        aclk_100, aclk_160, aclk_133);
1431
1432        clk_f.rate = armclk;
1433        clk_h.rate = sclk_dmc;
1434        clk_p.rate = aclk_100;
1435
1436        for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
1437                s3c_set_clksrc(&clksrcs[ptr], true);
1438}
1439
1440static struct clk *clks[] __initdata = {
1441        &clk_sclk_hdmi27m,
1442        &clk_sclk_hdmiphy,
1443        &clk_sclk_usbphy0,
1444        &clk_sclk_usbphy1,
1445};
1446
1447#ifdef CONFIG_PM_SLEEP
1448static int exynos4_clock_suspend(void)
1449{
1450        s3c_pm_do_save(exynos4_clock_save, ARRAY_SIZE(exynos4_clock_save));
1451        return 0;
1452}
1453
1454static void exynos4_clock_resume(void)
1455{
1456        s3c_pm_do_restore_core(exynos4_clock_save, ARRAY_SIZE(exynos4_clock_save));
1457}
1458
1459#else
1460#define exynos4_clock_suspend NULL
1461#define exynos4_clock_resume NULL
1462#endif
1463
1464struct syscore_ops exynos4_clock_syscore_ops = {
1465        .suspend        = exynos4_clock_suspend,
1466        .resume         = exynos4_clock_resume,
1467};
1468
1469void __init exynos4_register_clocks(void)
1470{
1471        int ptr;
1472
1473        s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
1474
1475        for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
1476                s3c_register_clksrc(sysclks[ptr], 1);
1477
1478        for (ptr = 0; ptr < ARRAY_SIZE(sclk_tv); ptr++)
1479                s3c_register_clksrc(sclk_tv[ptr], 1);
1480
1481        s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
1482        s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
1483
1484        s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1485        s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1486
1487        register_syscore_ops(&exynos4_clock_syscore_ops);
1488        s3c24xx_register_clock(&dummy_apb_pclk);
1489
1490        s3c_pwmclk_init();
1491}
1492
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.