linux/arch/arm/mach-s5pv310/clock.c
<<
>>
Prefs
   1/* linux/arch/arm/mach-s5pv310/clock.c
   2 *
   3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
   4 *              http://www.samsung.com/
   5 *
   6 * S5PV310 - 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
  17#include <plat/cpu-freq.h>
  18#include <plat/clock.h>
  19#include <plat/cpu.h>
  20#include <plat/pll.h>
  21#include <plat/s5p-clock.h>
  22#include <plat/clock-clksrc.h>
  23
  24#include <mach/map.h>
  25#include <mach/regs-clock.h>
  26
  27static struct clk clk_sclk_hdmi27m = {
  28        .name           = "sclk_hdmi27m",
  29        .id             = -1,
  30        .rate           = 27000000,
  31};
  32
  33static struct clk clk_sclk_hdmiphy = {
  34        .name           = "sclk_hdmiphy",
  35        .id             = -1,
  36};
  37
  38static struct clk clk_sclk_usbphy0 = {
  39        .name           = "sclk_usbphy0",
  40        .id             = -1,
  41        .rate           = 27000000,
  42};
  43
  44static struct clk clk_sclk_usbphy1 = {
  45        .name           = "sclk_usbphy1",
  46        .id             = -1,
  47};
  48
  49static int s5pv310_clksrc_mask_top_ctrl(struct clk *clk, int enable)
  50{
  51        return s5p_gatectrl(S5P_CLKSRC_MASK_TOP, clk, enable);
  52}
  53
  54static int s5pv310_clksrc_mask_cam_ctrl(struct clk *clk, int enable)
  55{
  56        return s5p_gatectrl(S5P_CLKSRC_MASK_CAM, clk, enable);
  57}
  58
  59static int s5pv310_clksrc_mask_lcd0_ctrl(struct clk *clk, int enable)
  60{
  61        return s5p_gatectrl(S5P_CLKSRC_MASK_LCD0, clk, enable);
  62}
  63
  64static int s5pv310_clksrc_mask_lcd1_ctrl(struct clk *clk, int enable)
  65{
  66        return s5p_gatectrl(S5P_CLKSRC_MASK_LCD1, clk, enable);
  67}
  68
  69static int s5pv310_clksrc_mask_fsys_ctrl(struct clk *clk, int enable)
  70{
  71        return s5p_gatectrl(S5P_CLKSRC_MASK_FSYS, clk, enable);
  72}
  73
  74static int s5pv310_clksrc_mask_peril0_ctrl(struct clk *clk, int enable)
  75{
  76        return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL0, clk, enable);
  77}
  78
  79static int s5pv310_clksrc_mask_peril1_ctrl(struct clk *clk, int enable)
  80{
  81        return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL1, clk, enable);
  82}
  83
  84static int s5pv310_clk_ip_cam_ctrl(struct clk *clk, int enable)
  85{
  86        return s5p_gatectrl(S5P_CLKGATE_IP_CAM, clk, enable);
  87}
  88
  89static int s5pv310_clk_ip_image_ctrl(struct clk *clk, int enable)
  90{
  91        return s5p_gatectrl(S5P_CLKGATE_IP_IMAGE, clk, enable);
  92}
  93
  94static int s5pv310_clk_ip_lcd0_ctrl(struct clk *clk, int enable)
  95{
  96        return s5p_gatectrl(S5P_CLKGATE_IP_LCD0, clk, enable);
  97}
  98
  99static int s5pv310_clk_ip_lcd1_ctrl(struct clk *clk, int enable)
 100{
 101        return s5p_gatectrl(S5P_CLKGATE_IP_LCD1, clk, enable);
 102}
 103
 104static int s5pv310_clk_ip_fsys_ctrl(struct clk *clk, int enable)
 105{
 106        return s5p_gatectrl(S5P_CLKGATE_IP_FSYS, clk, enable);
 107}
 108
 109static int s5pv310_clk_ip_peril_ctrl(struct clk *clk, int enable)
 110{
 111        return s5p_gatectrl(S5P_CLKGATE_IP_PERIL, clk, enable);
 112}
 113
 114static int s5pv310_clk_ip_perir_ctrl(struct clk *clk, int enable)
 115{
 116        return s5p_gatectrl(S5P_CLKGATE_IP_PERIR, clk, enable);
 117}
 118
 119/* Core list of CMU_CPU side */
 120
 121static struct clksrc_clk clk_mout_apll = {
 122        .clk    = {
 123                .name           = "mout_apll",
 124                .id             = -1,
 125        },
 126        .sources        = &clk_src_apll,
 127        .reg_src        = { .reg = S5P_CLKSRC_CPU, .shift = 0, .size = 1 },
 128};
 129
 130static struct clksrc_clk clk_sclk_apll = {
 131        .clk    = {
 132                .name           = "sclk_apll",
 133                .id             = -1,
 134                .parent         = &clk_mout_apll.clk,
 135        },
 136        .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 24, .size = 3 },
 137};
 138
 139static struct clksrc_clk clk_mout_epll = {
 140        .clk    = {
 141                .name           = "mout_epll",
 142                .id             = -1,
 143        },
 144        .sources        = &clk_src_epll,
 145        .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 4, .size = 1 },
 146};
 147
 148static struct clksrc_clk clk_mout_mpll = {
 149        .clk = {
 150                .name           = "mout_mpll",
 151                .id             = -1,
 152        },
 153        .sources        = &clk_src_mpll,
 154        .reg_src        = { .reg = S5P_CLKSRC_CPU, .shift = 8, .size = 1 },
 155};
 156
 157static struct clk *clkset_moutcore_list[] = {
 158        [0] = &clk_mout_apll.clk,
 159        [1] = &clk_mout_mpll.clk,
 160};
 161
 162static struct clksrc_sources clkset_moutcore = {
 163        .sources        = clkset_moutcore_list,
 164        .nr_sources     = ARRAY_SIZE(clkset_moutcore_list),
 165};
 166
 167static struct clksrc_clk clk_moutcore = {
 168        .clk    = {
 169                .name           = "moutcore",
 170                .id             = -1,
 171        },
 172        .sources        = &clkset_moutcore,
 173        .reg_src        = { .reg = S5P_CLKSRC_CPU, .shift = 16, .size = 1 },
 174};
 175
 176static struct clksrc_clk clk_coreclk = {
 177        .clk    = {
 178                .name           = "core_clk",
 179                .id             = -1,
 180                .parent         = &clk_moutcore.clk,
 181        },
 182        .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 0, .size = 3 },
 183};
 184
 185static struct clksrc_clk clk_armclk = {
 186        .clk    = {
 187                .name           = "armclk",
 188                .id             = -1,
 189                .parent         = &clk_coreclk.clk,
 190        },
 191};
 192
 193static struct clksrc_clk clk_aclk_corem0 = {
 194        .clk    = {
 195                .name           = "aclk_corem0",
 196                .id             = -1,
 197                .parent         = &clk_coreclk.clk,
 198        },
 199        .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 4, .size = 3 },
 200};
 201
 202static struct clksrc_clk clk_aclk_cores = {
 203        .clk    = {
 204                .name           = "aclk_cores",
 205                .id             = -1,
 206                .parent         = &clk_coreclk.clk,
 207        },
 208        .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 4, .size = 3 },
 209};
 210
 211static struct clksrc_clk clk_aclk_corem1 = {
 212        .clk    = {
 213                .name           = "aclk_corem1",
 214                .id             = -1,
 215                .parent         = &clk_coreclk.clk,
 216        },
 217        .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 8, .size = 3 },
 218};
 219
 220static struct clksrc_clk clk_periphclk = {
 221        .clk    = {
 222                .name           = "periphclk",
 223                .id             = -1,
 224                .parent         = &clk_coreclk.clk,
 225        },
 226        .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 12, .size = 3 },
 227};
 228
 229/* Core list of CMU_CORE side */
 230
 231static struct clk *clkset_corebus_list[] = {
 232        [0] = &clk_mout_mpll.clk,
 233        [1] = &clk_sclk_apll.clk,
 234};
 235
 236static struct clksrc_sources clkset_mout_corebus = {
 237        .sources        = clkset_corebus_list,
 238        .nr_sources     = ARRAY_SIZE(clkset_corebus_list),
 239};
 240
 241static struct clksrc_clk clk_mout_corebus = {
 242        .clk    = {
 243                .name           = "mout_corebus",
 244                .id             = -1,
 245        },
 246        .sources        = &clkset_mout_corebus,
 247        .reg_src        = { .reg = S5P_CLKSRC_DMC, .shift = 4, .size = 1 },
 248};
 249
 250static struct clksrc_clk clk_sclk_dmc = {
 251        .clk    = {
 252                .name           = "sclk_dmc",
 253                .id             = -1,
 254                .parent         = &clk_mout_corebus.clk,
 255        },
 256        .reg_div        = { .reg = S5P_CLKDIV_DMC0, .shift = 12, .size = 3 },
 257};
 258
 259static struct clksrc_clk clk_aclk_cored = {
 260        .clk    = {
 261                .name           = "aclk_cored",
 262                .id             = -1,
 263                .parent         = &clk_sclk_dmc.clk,
 264        },
 265        .reg_div        = { .reg = S5P_CLKDIV_DMC0, .shift = 16, .size = 3 },
 266};
 267
 268static struct clksrc_clk clk_aclk_corep = {
 269        .clk    = {
 270                .name           = "aclk_corep",
 271                .id             = -1,
 272                .parent         = &clk_aclk_cored.clk,
 273        },
 274        .reg_div        = { .reg = S5P_CLKDIV_DMC0, .shift = 20, .size = 3 },
 275};
 276
 277static struct clksrc_clk clk_aclk_acp = {
 278        .clk    = {
 279                .name           = "aclk_acp",
 280                .id             = -1,
 281                .parent         = &clk_mout_corebus.clk,
 282        },
 283        .reg_div        = { .reg = S5P_CLKDIV_DMC0, .shift = 0, .size = 3 },
 284};
 285
 286static struct clksrc_clk clk_pclk_acp = {
 287        .clk    = {
 288                .name           = "pclk_acp",
 289                .id             = -1,
 290                .parent         = &clk_aclk_acp.clk,
 291        },
 292        .reg_div        = { .reg = S5P_CLKDIV_DMC0, .shift = 4, .size = 3 },
 293};
 294
 295/* Core list of CMU_TOP side */
 296
 297static struct clk *clkset_aclk_top_list[] = {
 298        [0] = &clk_mout_mpll.clk,
 299        [1] = &clk_sclk_apll.clk,
 300};
 301
 302static struct clksrc_sources clkset_aclk = {
 303        .sources        = clkset_aclk_top_list,
 304        .nr_sources     = ARRAY_SIZE(clkset_aclk_top_list),
 305};
 306
 307static struct clksrc_clk clk_aclk_200 = {
 308        .clk    = {
 309                .name           = "aclk_200",
 310                .id             = -1,
 311        },
 312        .sources        = &clkset_aclk,
 313        .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 12, .size = 1 },
 314        .reg_div        = { .reg = S5P_CLKDIV_TOP, .shift = 0, .size = 3 },
 315};
 316
 317static struct clksrc_clk clk_aclk_100 = {
 318        .clk    = {
 319                .name           = "aclk_100",
 320                .id             = -1,
 321        },
 322        .sources        = &clkset_aclk,
 323        .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 16, .size = 1 },
 324        .reg_div        = { .reg = S5P_CLKDIV_TOP, .shift = 4, .size = 4 },
 325};
 326
 327static struct clksrc_clk clk_aclk_160 = {
 328        .clk    = {
 329                .name           = "aclk_160",
 330                .id             = -1,
 331        },
 332        .sources        = &clkset_aclk,
 333        .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 20, .size = 1 },
 334        .reg_div        = { .reg = S5P_CLKDIV_TOP, .shift = 8, .size = 3 },
 335};
 336
 337static struct clksrc_clk clk_aclk_133 = {
 338        .clk    = {
 339                .name           = "aclk_133",
 340                .id             = -1,
 341        },
 342        .sources        = &clkset_aclk,
 343        .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 24, .size = 1 },
 344        .reg_div        = { .reg = S5P_CLKDIV_TOP, .shift = 12, .size = 3 },
 345};
 346
 347static struct clk *clkset_vpllsrc_list[] = {
 348        [0] = &clk_fin_vpll,
 349        [1] = &clk_sclk_hdmi27m,
 350};
 351
 352static struct clksrc_sources clkset_vpllsrc = {
 353        .sources        = clkset_vpllsrc_list,
 354        .nr_sources     = ARRAY_SIZE(clkset_vpllsrc_list),
 355};
 356
 357static struct clksrc_clk clk_vpllsrc = {
 358        .clk    = {
 359                .name           = "vpll_src",
 360                .id             = -1,
 361                .enable         = s5pv310_clksrc_mask_top_ctrl,
 362                .ctrlbit        = (1 << 0),
 363        },
 364        .sources        = &clkset_vpllsrc,
 365        .reg_src        = { .reg = S5P_CLKSRC_TOP1, .shift = 0, .size = 1 },
 366};
 367
 368static struct clk *clkset_sclk_vpll_list[] = {
 369        [0] = &clk_vpllsrc.clk,
 370        [1] = &clk_fout_vpll,
 371};
 372
 373static struct clksrc_sources clkset_sclk_vpll = {
 374        .sources        = clkset_sclk_vpll_list,
 375        .nr_sources     = ARRAY_SIZE(clkset_sclk_vpll_list),
 376};
 377
 378static struct clksrc_clk clk_sclk_vpll = {
 379        .clk    = {
 380                .name           = "sclk_vpll",
 381                .id             = -1,
 382        },
 383        .sources        = &clkset_sclk_vpll,
 384        .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 8, .size = 1 },
 385};
 386
 387static struct clk init_clocks_off[] = {
 388        {
 389                .name           = "timers",
 390                .id             = -1,
 391                .parent         = &clk_aclk_100.clk,
 392                .enable         = s5pv310_clk_ip_peril_ctrl,
 393                .ctrlbit        = (1<<24),
 394        }, {
 395                .name           = "csis",
 396                .id             = 0,
 397                .enable         = s5pv310_clk_ip_cam_ctrl,
 398                .ctrlbit        = (1 << 4),
 399        }, {
 400                .name           = "csis",
 401                .id             = 1,
 402                .enable         = s5pv310_clk_ip_cam_ctrl,
 403                .ctrlbit        = (1 << 5),
 404        }, {
 405                .name           = "fimc",
 406                .id             = 0,
 407                .enable         = s5pv310_clk_ip_cam_ctrl,
 408                .ctrlbit        = (1 << 0),
 409        }, {
 410                .name           = "fimc",
 411                .id             = 1,
 412                .enable         = s5pv310_clk_ip_cam_ctrl,
 413                .ctrlbit        = (1 << 1),
 414        }, {
 415                .name           = "fimc",
 416                .id             = 2,
 417                .enable         = s5pv310_clk_ip_cam_ctrl,
 418                .ctrlbit        = (1 << 2),
 419        }, {
 420                .name           = "fimc",
 421                .id             = 3,
 422                .enable         = s5pv310_clk_ip_cam_ctrl,
 423                .ctrlbit        = (1 << 3),
 424        }, {
 425                .name           = "fimd",
 426                .id             = 0,
 427                .enable         = s5pv310_clk_ip_lcd0_ctrl,
 428                .ctrlbit        = (1 << 0),
 429        }, {
 430                .name           = "fimd",
 431                .id             = 1,
 432                .enable         = s5pv310_clk_ip_lcd1_ctrl,
 433                .ctrlbit        = (1 << 0),
 434        }, {
 435                .name           = "hsmmc",
 436                .id             = 0,
 437                .parent         = &clk_aclk_133.clk,
 438                .enable         = s5pv310_clk_ip_fsys_ctrl,
 439                .ctrlbit        = (1 << 5),
 440        }, {
 441                .name           = "hsmmc",
 442                .id             = 1,
 443                .parent         = &clk_aclk_133.clk,
 444                .enable         = s5pv310_clk_ip_fsys_ctrl,
 445                .ctrlbit        = (1 << 6),
 446        }, {
 447                .name           = "hsmmc",
 448                .id             = 2,
 449                .parent         = &clk_aclk_133.clk,
 450                .enable         = s5pv310_clk_ip_fsys_ctrl,
 451                .ctrlbit        = (1 << 7),
 452        }, {
 453                .name           = "hsmmc",
 454                .id             = 3,
 455                .parent         = &clk_aclk_133.clk,
 456                .enable         = s5pv310_clk_ip_fsys_ctrl,
 457                .ctrlbit        = (1 << 8),
 458        }, {
 459                .name           = "hsmmc",
 460                .id             = 4,
 461                .parent         = &clk_aclk_133.clk,
 462                .enable         = s5pv310_clk_ip_fsys_ctrl,
 463                .ctrlbit        = (1 << 9),
 464        }, {
 465                .name           = "sata",
 466                .id             = -1,
 467                .enable         = s5pv310_clk_ip_fsys_ctrl,
 468                .ctrlbit        = (1 << 10),
 469        }, {
 470                .name           = "pdma",
 471                .id             = 0,
 472                .enable         = s5pv310_clk_ip_fsys_ctrl,
 473                .ctrlbit        = (1 << 0),
 474        }, {
 475                .name           = "pdma",
 476                .id             = 1,
 477                .enable         = s5pv310_clk_ip_fsys_ctrl,
 478                .ctrlbit        = (1 << 1),
 479        }, {
 480                .name           = "adc",
 481                .id             = -1,
 482                .enable         = s5pv310_clk_ip_peril_ctrl,
 483                .ctrlbit        = (1 << 15),
 484        }, {
 485                .name           = "rtc",
 486                .id             = -1,
 487                .enable         = s5pv310_clk_ip_perir_ctrl,
 488                .ctrlbit        = (1 << 15),
 489        }, {
 490                .name           = "watchdog",
 491                .id             = -1,
 492                .enable         = s5pv310_clk_ip_perir_ctrl,
 493                .ctrlbit        = (1 << 14),
 494        }, {
 495                .name           = "usbhost",
 496                .id             = -1,
 497                .enable         = s5pv310_clk_ip_fsys_ctrl ,
 498                .ctrlbit        = (1 << 12),
 499        }, {
 500                .name           = "otg",
 501                .id             = -1,
 502                .enable         = s5pv310_clk_ip_fsys_ctrl,
 503                .ctrlbit        = (1 << 13),
 504        }, {
 505                .name           = "spi",
 506                .id             = 0,
 507                .enable         = s5pv310_clk_ip_peril_ctrl,
 508                .ctrlbit        = (1 << 16),
 509        }, {
 510                .name           = "spi",
 511                .id             = 1,
 512                .enable         = s5pv310_clk_ip_peril_ctrl,
 513                .ctrlbit        = (1 << 17),
 514        }, {
 515                .name           = "spi",
 516                .id             = 2,
 517                .enable         = s5pv310_clk_ip_peril_ctrl,
 518                .ctrlbit        = (1 << 18),
 519        }, {
 520                .name           = "iis",
 521                .id             = 0,
 522                .enable         = s5pv310_clk_ip_peril_ctrl,
 523                .ctrlbit        = (1 << 19),
 524        }, {
 525                .name           = "iis",
 526                .id             = 1,
 527                .enable         = s5pv310_clk_ip_peril_ctrl,
 528                .ctrlbit        = (1 << 20),
 529        }, {
 530                .name           = "iis",
 531                .id             = 2,
 532                .enable         = s5pv310_clk_ip_peril_ctrl,
 533                .ctrlbit        = (1 << 21),
 534        }, {
 535                .name           = "ac97",
 536                .id             = -1,
 537                .enable         = s5pv310_clk_ip_peril_ctrl,
 538                .ctrlbit        = (1 << 27),
 539        }, {
 540                .name           = "fimg2d",
 541                .id             = -1,
 542                .enable         = s5pv310_clk_ip_image_ctrl,
 543                .ctrlbit        = (1 << 0),
 544        }, {
 545                .name           = "i2c",
 546                .id             = 0,
 547                .parent         = &clk_aclk_100.clk,
 548                .enable         = s5pv310_clk_ip_peril_ctrl,
 549                .ctrlbit        = (1 << 6),
 550        }, {
 551                .name           = "i2c",
 552                .id             = 1,
 553                .parent         = &clk_aclk_100.clk,
 554                .enable         = s5pv310_clk_ip_peril_ctrl,
 555                .ctrlbit        = (1 << 7),
 556        }, {
 557                .name           = "i2c",
 558                .id             = 2,
 559                .parent         = &clk_aclk_100.clk,
 560                .enable         = s5pv310_clk_ip_peril_ctrl,
 561                .ctrlbit        = (1 << 8),
 562        }, {
 563                .name           = "i2c",
 564                .id             = 3,
 565                .parent         = &clk_aclk_100.clk,
 566                .enable         = s5pv310_clk_ip_peril_ctrl,
 567                .ctrlbit        = (1 << 9),
 568        }, {
 569                .name           = "i2c",
 570                .id             = 4,
 571                .parent         = &clk_aclk_100.clk,
 572                .enable         = s5pv310_clk_ip_peril_ctrl,
 573                .ctrlbit        = (1 << 10),
 574        }, {
 575                .name           = "i2c",
 576                .id             = 5,
 577                .parent         = &clk_aclk_100.clk,
 578                .enable         = s5pv310_clk_ip_peril_ctrl,
 579                .ctrlbit        = (1 << 11),
 580        }, {
 581                .name           = "i2c",
 582                .id             = 6,
 583                .parent         = &clk_aclk_100.clk,
 584                .enable         = s5pv310_clk_ip_peril_ctrl,
 585                .ctrlbit        = (1 << 12),
 586        }, {
 587                .name           = "i2c",
 588                .id             = 7,
 589                .parent         = &clk_aclk_100.clk,
 590                .enable         = s5pv310_clk_ip_peril_ctrl,
 591                .ctrlbit        = (1 << 13),
 592        },
 593};
 594
 595static struct clk init_clocks[] = {
 596        {
 597                .name           = "uart",
 598                .id             = 0,
 599                .enable         = s5pv310_clk_ip_peril_ctrl,
 600                .ctrlbit        = (1 << 0),
 601        }, {
 602                .name           = "uart",
 603                .id             = 1,
 604                .enable         = s5pv310_clk_ip_peril_ctrl,
 605                .ctrlbit        = (1 << 1),
 606        }, {
 607                .name           = "uart",
 608                .id             = 2,
 609                .enable         = s5pv310_clk_ip_peril_ctrl,
 610                .ctrlbit        = (1 << 2),
 611        }, {
 612                .name           = "uart",
 613                .id             = 3,
 614                .enable         = s5pv310_clk_ip_peril_ctrl,
 615                .ctrlbit        = (1 << 3),
 616        }, {
 617                .name           = "uart",
 618                .id             = 4,
 619                .enable         = s5pv310_clk_ip_peril_ctrl,
 620                .ctrlbit        = (1 << 4),
 621        }, {
 622                .name           = "uart",
 623                .id             = 5,
 624                .enable         = s5pv310_clk_ip_peril_ctrl,
 625                .ctrlbit        = (1 << 5),
 626        }
 627};
 628
 629static struct clk *clkset_group_list[] = {
 630        [0] = &clk_ext_xtal_mux,
 631        [1] = &clk_xusbxti,
 632        [2] = &clk_sclk_hdmi27m,
 633        [3] = &clk_sclk_usbphy0,
 634        [4] = &clk_sclk_usbphy1,
 635        [5] = &clk_sclk_hdmiphy,
 636        [6] = &clk_mout_mpll.clk,
 637        [7] = &clk_mout_epll.clk,
 638        [8] = &clk_sclk_vpll.clk,
 639};
 640
 641static struct clksrc_sources clkset_group = {
 642        .sources        = clkset_group_list,
 643        .nr_sources     = ARRAY_SIZE(clkset_group_list),
 644};
 645
 646static struct clk *clkset_mout_g2d0_list[] = {
 647        [0] = &clk_mout_mpll.clk,
 648        [1] = &clk_sclk_apll.clk,
 649};
 650
 651static struct clksrc_sources clkset_mout_g2d0 = {
 652        .sources        = clkset_mout_g2d0_list,
 653        .nr_sources     = ARRAY_SIZE(clkset_mout_g2d0_list),
 654};
 655
 656static struct clksrc_clk clk_mout_g2d0 = {
 657        .clk    = {
 658                .name           = "mout_g2d0",
 659                .id             = -1,
 660        },
 661        .sources        = &clkset_mout_g2d0,
 662        .reg_src        = { .reg = S5P_CLKSRC_IMAGE, .shift = 0, .size = 1 },
 663};
 664
 665static struct clk *clkset_mout_g2d1_list[] = {
 666        [0] = &clk_mout_epll.clk,
 667        [1] = &clk_sclk_vpll.clk,
 668};
 669
 670static struct clksrc_sources clkset_mout_g2d1 = {
 671        .sources        = clkset_mout_g2d1_list,
 672        .nr_sources     = ARRAY_SIZE(clkset_mout_g2d1_list),
 673};
 674
 675static struct clksrc_clk clk_mout_g2d1 = {
 676        .clk    = {
 677                .name           = "mout_g2d1",
 678                .id             = -1,
 679        },
 680        .sources        = &clkset_mout_g2d1,
 681        .reg_src        = { .reg = S5P_CLKSRC_IMAGE, .shift = 4, .size = 1 },
 682};
 683
 684static struct clk *clkset_mout_g2d_list[] = {
 685        [0] = &clk_mout_g2d0.clk,
 686        [1] = &clk_mout_g2d1.clk,
 687};
 688
 689static struct clksrc_sources clkset_mout_g2d = {
 690        .sources        = clkset_mout_g2d_list,
 691        .nr_sources     = ARRAY_SIZE(clkset_mout_g2d_list),
 692};
 693
 694static struct clksrc_clk clk_dout_mmc0 = {
 695        .clk            = {
 696                .name           = "dout_mmc0",
 697                .id             = -1,
 698        },
 699        .sources = &clkset_group,
 700        .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 0, .size = 4 },
 701        .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 0, .size = 4 },
 702};
 703
 704static struct clksrc_clk clk_dout_mmc1 = {
 705        .clk            = {
 706                .name           = "dout_mmc1",
 707                .id             = -1,
 708        },
 709        .sources = &clkset_group,
 710        .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 4, .size = 4 },
 711        .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 16, .size = 4 },
 712};
 713
 714static struct clksrc_clk clk_dout_mmc2 = {
 715        .clk            = {
 716                .name           = "dout_mmc2",
 717                .id             = -1,
 718        },
 719        .sources = &clkset_group,
 720        .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 8, .size = 4 },
 721        .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 0, .size = 4 },
 722};
 723
 724static struct clksrc_clk clk_dout_mmc3 = {
 725        .clk            = {
 726                .name           = "dout_mmc3",
 727                .id             = -1,
 728        },
 729        .sources = &clkset_group,
 730        .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 12, .size = 4 },
 731        .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 16, .size = 4 },
 732};
 733
 734static struct clksrc_clk clk_dout_mmc4 = {
 735        .clk            = {
 736                .name           = "dout_mmc4",
 737                .id             = -1,
 738        },
 739        .sources = &clkset_group,
 740        .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 16, .size = 4 },
 741        .reg_div = { .reg = S5P_CLKDIV_FSYS3, .shift = 0, .size = 4 },
 742};
 743
 744static struct clksrc_clk clksrcs[] = {
 745        {
 746                .clk    = {
 747                        .name           = "uclk1",
 748                        .id             = 0,
 749                        .enable         = s5pv310_clksrc_mask_peril0_ctrl,
 750                        .ctrlbit        = (1 << 0),
 751                },
 752                .sources = &clkset_group,
 753                .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 0, .size = 4 },
 754                .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 0, .size = 4 },
 755        }, {
 756                .clk            = {
 757                        .name           = "uclk1",
 758                        .id             = 1,
 759                        .enable         = s5pv310_clksrc_mask_peril0_ctrl,
 760                        .ctrlbit        = (1 << 4),
 761                },
 762                .sources = &clkset_group,
 763                .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 4, .size = 4 },
 764                .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 4, .size = 4 },
 765        }, {
 766                .clk            = {
 767                        .name           = "uclk1",
 768                        .id             = 2,
 769                        .enable         = s5pv310_clksrc_mask_peril0_ctrl,
 770                        .ctrlbit        = (1 << 8),
 771                },
 772                .sources = &clkset_group,
 773                .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 8, .size = 4 },
 774                .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 8, .size = 4 },
 775        }, {
 776                .clk            = {
 777                        .name           = "uclk1",
 778                        .id             = 3,
 779                        .enable         = s5pv310_clksrc_mask_peril0_ctrl,
 780                        .ctrlbit        = (1 << 12),
 781                },
 782                .sources = &clkset_group,
 783                .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 12, .size = 4 },
 784                .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 12, .size = 4 },
 785        }, {
 786                .clk            = {
 787                        .name           = "sclk_pwm",
 788                        .id             = -1,
 789                        .enable         = s5pv310_clksrc_mask_peril0_ctrl,
 790                        .ctrlbit        = (1 << 24),
 791                },
 792                .sources = &clkset_group,
 793                .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 24, .size = 4 },
 794                .reg_div = { .reg = S5P_CLKDIV_PERIL3, .shift = 0, .size = 4 },
 795        }, {
 796                .clk            = {
 797                        .name           = "sclk_csis",
 798                        .id             = 0,
 799                        .enable         = s5pv310_clksrc_mask_cam_ctrl,
 800                        .ctrlbit        = (1 << 24),
 801                },
 802                .sources = &clkset_group,
 803                .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 24, .size = 4 },
 804                .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 24, .size = 4 },
 805        }, {
 806                .clk            = {
 807                        .name           = "sclk_csis",
 808                        .id             = 1,
 809                        .enable         = s5pv310_clksrc_mask_cam_ctrl,
 810                        .ctrlbit        = (1 << 28),
 811                },
 812                .sources = &clkset_group,
 813                .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 28, .size = 4 },
 814                .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 28, .size = 4 },
 815        }, {
 816                .clk            = {
 817                        .name           = "sclk_cam",
 818                        .id             = 0,
 819                        .enable         = s5pv310_clksrc_mask_cam_ctrl,
 820                        .ctrlbit        = (1 << 16),
 821                },
 822                .sources = &clkset_group,
 823                .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 16, .size = 4 },
 824                .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 16, .size = 4 },
 825        }, {
 826                .clk            = {
 827                        .name           = "sclk_cam",
 828                        .id             = 1,
 829                        .enable         = s5pv310_clksrc_mask_cam_ctrl,
 830                        .ctrlbit        = (1 << 20),
 831                },
 832                .sources = &clkset_group,
 833                .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 20, .size = 4 },
 834                .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 20, .size = 4 },
 835        }, {
 836                .clk            = {
 837                        .name           = "sclk_fimc",
 838                        .id             = 0,
 839                        .enable         = s5pv310_clksrc_mask_cam_ctrl,
 840                        .ctrlbit        = (1 << 0),
 841                },
 842                .sources = &clkset_group,
 843                .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 0, .size = 4 },
 844                .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 0, .size = 4 },
 845        }, {
 846                .clk            = {
 847                        .name           = "sclk_fimc",
 848                        .id             = 1,
 849                        .enable         = s5pv310_clksrc_mask_cam_ctrl,
 850                        .ctrlbit        = (1 << 4),
 851                },
 852                .sources = &clkset_group,
 853                .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 4, .size = 4 },
 854                .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 4, .size = 4 },
 855        }, {
 856                .clk            = {
 857                        .name           = "sclk_fimc",
 858                        .id             = 2,
 859                        .enable         = s5pv310_clksrc_mask_cam_ctrl,
 860                        .ctrlbit        = (1 << 8),
 861                },
 862                .sources = &clkset_group,
 863                .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 8, .size = 4 },
 864                .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 8, .size = 4 },
 865        }, {
 866                .clk            = {
 867                        .name           = "sclk_fimc",
 868                        .id             = 3,
 869                        .enable         = s5pv310_clksrc_mask_cam_ctrl,
 870                        .ctrlbit        = (1 << 12),
 871                },
 872                .sources = &clkset_group,
 873                .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 12, .size = 4 },
 874                .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 12, .size = 4 },
 875        }, {
 876                .clk            = {
 877                        .name           = "sclk_fimd",
 878                        .id             = 0,
 879                        .enable         = s5pv310_clksrc_mask_lcd0_ctrl,
 880                        .ctrlbit        = (1 << 0),
 881                },
 882                .sources = &clkset_group,
 883                .reg_src = { .reg = S5P_CLKSRC_LCD0, .shift = 0, .size = 4 },
 884                .reg_div = { .reg = S5P_CLKDIV_LCD0, .shift = 0, .size = 4 },
 885        }, {
 886                .clk            = {
 887                        .name           = "sclk_fimd",
 888                        .id             = 1,
 889                        .enable         = s5pv310_clksrc_mask_lcd1_ctrl,
 890                        .ctrlbit        = (1 << 0),
 891                },
 892                .sources = &clkset_group,
 893                .reg_src = { .reg = S5P_CLKSRC_LCD1, .shift = 0, .size = 4 },
 894                .reg_div = { .reg = S5P_CLKDIV_LCD1, .shift = 0, .size = 4 },
 895        }, {
 896                .clk            = {
 897                        .name           = "sclk_sata",
 898                        .id             = -1,
 899                        .enable         = s5pv310_clksrc_mask_fsys_ctrl,
 900                        .ctrlbit        = (1 << 24),
 901                },
 902                .sources = &clkset_mout_corebus,
 903                .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 24, .size = 1 },
 904                .reg_div = { .reg = S5P_CLKDIV_FSYS0, .shift = 20, .size = 4 },
 905        }, {
 906                .clk            = {
 907                        .name           = "sclk_spi",
 908                        .id             = 0,
 909                        .enable         = s5pv310_clksrc_mask_peril1_ctrl,
 910                        .ctrlbit        = (1 << 16),
 911                },
 912                .sources = &clkset_group,
 913                .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 16, .size = 4 },
 914                .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 0, .size = 4 },
 915        }, {
 916                .clk            = {
 917                        .name           = "sclk_spi",
 918                        .id             = 1,
 919                        .enable         = s5pv310_clksrc_mask_peril1_ctrl,
 920                        .ctrlbit        = (1 << 20),
 921                },
 922                .sources = &clkset_group,
 923                .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 20, .size = 4 },
 924                .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 16, .size = 4 },
 925        }, {
 926                .clk            = {
 927                        .name           = "sclk_spi",
 928                        .id             = 2,
 929                        .enable         = s5pv310_clksrc_mask_peril1_ctrl,
 930                        .ctrlbit        = (1 << 24),
 931                },
 932                .sources = &clkset_group,
 933                .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 24, .size = 4 },
 934                .reg_div = { .reg = S5P_CLKDIV_PERIL2, .shift = 0, .size = 4 },
 935        }, {
 936                .clk            = {
 937                        .name           = "sclk_fimg2d",
 938                        .id             = -1,
 939                },
 940                .sources = &clkset_mout_g2d,
 941                .reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 8, .size = 1 },
 942                .reg_div = { .reg = S5P_CLKDIV_IMAGE, .shift = 0, .size = 4 },
 943        }, {
 944                .clk            = {
 945                        .name           = "sclk_mmc",
 946                        .id             = 0,
 947                        .parent         = &clk_dout_mmc0.clk,
 948                        .enable         = s5pv310_clksrc_mask_fsys_ctrl,
 949                        .ctrlbit        = (1 << 0),
 950                },
 951                .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 8, .size = 8 },
 952        }, {
 953                .clk            = {
 954                        .name           = "sclk_mmc",
 955                        .id             = 1,
 956                        .parent         = &clk_dout_mmc1.clk,
 957                        .enable         = s5pv310_clksrc_mask_fsys_ctrl,
 958                        .ctrlbit        = (1 << 4),
 959                },
 960                .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 24, .size = 8 },
 961        }, {
 962                .clk            = {
 963                        .name           = "sclk_mmc",
 964                        .id             = 2,
 965                        .parent         = &clk_dout_mmc2.clk,
 966                        .enable         = s5pv310_clksrc_mask_fsys_ctrl,
 967                        .ctrlbit        = (1 << 8),
 968                },
 969                .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 8, .size = 8 },
 970        }, {
 971                .clk            = {
 972                        .name           = "sclk_mmc",
 973                        .id             = 3,
 974                        .parent         = &clk_dout_mmc3.clk,
 975                        .enable         = s5pv310_clksrc_mask_fsys_ctrl,
 976                        .ctrlbit        = (1 << 12),
 977                },
 978                .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 24, .size = 8 },
 979        }, {
 980                .clk            = {
 981                        .name           = "sclk_mmc",
 982                        .id             = 4,
 983                        .parent         = &clk_dout_mmc4.clk,
 984                        .enable         = s5pv310_clksrc_mask_fsys_ctrl,
 985                        .ctrlbit        = (1 << 16),
 986                },
 987                .reg_div = { .reg = S5P_CLKDIV_FSYS3, .shift = 8, .size = 8 },
 988        }
 989};
 990
 991/* Clock initialization code */
 992static struct clksrc_clk *sysclks[] = {
 993        &clk_mout_apll,
 994        &clk_sclk_apll,
 995        &clk_mout_epll,
 996        &clk_mout_mpll,
 997        &clk_moutcore,
 998        &clk_coreclk,
 999        &clk_armclk,
1000        &clk_aclk_corem0,
1001        &clk_aclk_cores,
1002        &clk_aclk_corem1,
1003        &clk_periphclk,
1004        &clk_mout_corebus,
1005        &clk_sclk_dmc,
1006        &clk_aclk_cored,
1007        &clk_aclk_corep,
1008        &clk_aclk_acp,
1009        &clk_pclk_acp,
1010        &clk_vpllsrc,
1011        &clk_sclk_vpll,
1012        &clk_aclk_200,
1013        &clk_aclk_100,
1014        &clk_aclk_160,
1015        &clk_aclk_133,
1016        &clk_dout_mmc0,
1017        &clk_dout_mmc1,
1018        &clk_dout_mmc2,
1019        &clk_dout_mmc3,
1020        &clk_dout_mmc4,
1021};
1022
1023static int xtal_rate;
1024
1025static unsigned long s5pv310_fout_apll_get_rate(struct clk *clk)
1026{
1027        return s5p_get_pll45xx(xtal_rate, __raw_readl(S5P_APLL_CON0), pll_4508);
1028}
1029
1030static struct clk_ops s5pv310_fout_apll_ops = {
1031        .get_rate = s5pv310_fout_apll_get_rate,
1032};
1033
1034void __init_or_cpufreq s5pv310_setup_clocks(void)
1035{
1036        struct clk *xtal_clk;
1037        unsigned long apll;
1038        unsigned long mpll;
1039        unsigned long epll;
1040        unsigned long vpll;
1041        unsigned long vpllsrc;
1042        unsigned long xtal;
1043        unsigned long armclk;
1044        unsigned long sclk_dmc;
1045        unsigned long aclk_200;
1046        unsigned long aclk_100;
1047        unsigned long aclk_160;
1048        unsigned long aclk_133;
1049        unsigned int ptr;
1050
1051        printk(KERN_DEBUG "%s: registering clocks\n", __func__);
1052
1053        xtal_clk = clk_get(NULL, "xtal");
1054        BUG_ON(IS_ERR(xtal_clk));
1055
1056        xtal = clk_get_rate(xtal_clk);
1057
1058        xtal_rate = xtal;
1059
1060        clk_put(xtal_clk);
1061
1062        printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
1063
1064        apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON0), pll_4508);
1065        mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON0), pll_4508);
1066        epll = s5p_get_pll46xx(xtal, __raw_readl(S5P_EPLL_CON0),
1067                                __raw_readl(S5P_EPLL_CON1), pll_4600);
1068
1069        vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
1070        vpll = s5p_get_pll46xx(vpllsrc, __raw_readl(S5P_VPLL_CON0),
1071                                __raw_readl(S5P_VPLL_CON1), pll_4650);
1072
1073        clk_fout_apll.ops = &s5pv310_fout_apll_ops;
1074        clk_fout_mpll.rate = mpll;
1075        clk_fout_epll.rate = epll;
1076        clk_fout_vpll.rate = vpll;
1077
1078        printk(KERN_INFO "S5PV310: PLL settings, A=%ld, M=%ld, E=%ld V=%ld",
1079                        apll, mpll, epll, vpll);
1080
1081        armclk = clk_get_rate(&clk_armclk.clk);
1082        sclk_dmc = clk_get_rate(&clk_sclk_dmc.clk);
1083
1084        aclk_200 = clk_get_rate(&clk_aclk_200.clk);
1085        aclk_100 = clk_get_rate(&clk_aclk_100.clk);
1086        aclk_160 = clk_get_rate(&clk_aclk_160.clk);
1087        aclk_133 = clk_get_rate(&clk_aclk_133.clk);
1088
1089        printk(KERN_INFO "S5PV310: ARMCLK=%ld, DMC=%ld, ACLK200=%ld\n"
1090                         "ACLK100=%ld, ACLK160=%ld, ACLK133=%ld\n",
1091                        armclk, sclk_dmc, aclk_200,
1092                        aclk_100, aclk_160, aclk_133);
1093
1094        clk_f.rate = armclk;
1095        clk_h.rate = sclk_dmc;
1096        clk_p.rate = aclk_100;
1097
1098        for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
1099                s3c_set_clksrc(&clksrcs[ptr], true);
1100}
1101
1102static struct clk *clks[] __initdata = {
1103        /* Nothing here yet */
1104};
1105
1106void __init s5pv310_register_clocks(void)
1107{
1108        int ptr;
1109
1110        s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
1111
1112        for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
1113                s3c_register_clksrc(sysclks[ptr], 1);
1114
1115        s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
1116        s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
1117
1118        s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1119        s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1120
1121        s3c_pwmclk_init();
1122}
1123