linux/arch/arm/mach-s3c24xx/common-s3c2443.c
<<
>>
Prefs
   1/*
   2 * Common code for SoCs starting with the S3C2443
   3 *
   4 * Copyright (c) 2007, 2010 Simtec Electronics
   5 *      Ben Dooks <ben@simtec.co.uk>
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License as published by
   9 * the Free Software Foundation; either version 2 of the License, or
  10 * (at your option) any later version.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 */
  17
  18#include <linux/init.h>
  19#include <linux/clk.h>
  20#include <linux/io.h>
  21
  22#include <mach/regs-s3c2443-clock.h>
  23
  24#include <plat/clock.h>
  25#include <plat/clock-clksrc.h>
  26#include <plat/cpu.h>
  27
  28#include <plat/cpu-freq.h>
  29
  30
  31static int s3c2443_gate(void __iomem *reg, struct clk *clk, int enable)
  32{
  33        u32 ctrlbit = clk->ctrlbit;
  34        u32 con = __raw_readl(reg);
  35
  36        if (enable)
  37                con |= ctrlbit;
  38        else
  39                con &= ~ctrlbit;
  40
  41        __raw_writel(con, reg);
  42        return 0;
  43}
  44
  45int s3c2443_clkcon_enable_h(struct clk *clk, int enable)
  46{
  47        return s3c2443_gate(S3C2443_HCLKCON, clk, enable);
  48}
  49
  50int s3c2443_clkcon_enable_p(struct clk *clk, int enable)
  51{
  52        return s3c2443_gate(S3C2443_PCLKCON, clk, enable);
  53}
  54
  55int s3c2443_clkcon_enable_s(struct clk *clk, int enable)
  56{
  57        return s3c2443_gate(S3C2443_SCLKCON, clk, enable);
  58}
  59
  60/* mpllref is a direct descendant of clk_xtal by default, but it is not
  61 * elided as the EPLL can be either sourced by the XTAL or EXTCLK and as
  62 * such directly equating the two source clocks is impossible.
  63 */
  64static struct clk clk_mpllref = {
  65        .name           = "mpllref",
  66        .parent         = &clk_xtal,
  67};
  68
  69static struct clk *clk_epllref_sources[] = {
  70        [0] = &clk_mpllref,
  71        [1] = &clk_mpllref,
  72        [2] = &clk_xtal,
  73        [3] = &clk_ext,
  74};
  75
  76struct clksrc_clk clk_epllref = {
  77        .clk    = {
  78                .name           = "epllref",
  79        },
  80        .sources = &(struct clksrc_sources) {
  81                .sources = clk_epllref_sources,
  82                .nr_sources = ARRAY_SIZE(clk_epllref_sources),
  83        },
  84        .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 7 },
  85};
  86
  87/* esysclk
  88 *
  89 * this is sourced from either the EPLL or the EPLLref clock
  90*/
  91
  92static struct clk *clk_sysclk_sources[] = {
  93        [0] = &clk_epllref.clk,
  94        [1] = &clk_epll,
  95};
  96
  97struct clksrc_clk clk_esysclk = {
  98        .clk    = {
  99                .name           = "esysclk",
 100                .parent         = &clk_epll,
 101        },
 102        .sources = &(struct clksrc_sources) {
 103                .sources = clk_sysclk_sources,
 104                .nr_sources = ARRAY_SIZE(clk_sysclk_sources),
 105        },
 106        .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 6 },
 107};
 108
 109static unsigned long s3c2443_getrate_mdivclk(struct clk *clk)
 110{
 111        unsigned long parent_rate = clk_get_rate(clk->parent);
 112        unsigned long div = __raw_readl(S3C2443_CLKDIV0);
 113
 114        div  &= S3C2443_CLKDIV0_EXTDIV_MASK;
 115        div >>= (S3C2443_CLKDIV0_EXTDIV_SHIFT-1);       /* x2 */
 116
 117        return parent_rate / (div + 1);
 118}
 119
 120static struct clk clk_mdivclk = {
 121        .name           = "mdivclk",
 122        .parent         = &clk_mpllref,
 123        .ops            = &(struct clk_ops) {
 124                .get_rate       = s3c2443_getrate_mdivclk,
 125        },
 126};
 127
 128static struct clk *clk_msysclk_sources[] = {
 129        [0] = &clk_mpllref,
 130        [1] = &clk_mpll,
 131        [2] = &clk_mdivclk,
 132        [3] = &clk_mpllref,
 133};
 134
 135static struct clksrc_clk clk_msysclk = {
 136        .clk    = {
 137                .name           = "msysclk",
 138                .parent         = &clk_xtal,
 139        },
 140        .sources = &(struct clksrc_sources) {
 141                .sources = clk_msysclk_sources,
 142                .nr_sources = ARRAY_SIZE(clk_msysclk_sources),
 143        },
 144        .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 3 },
 145};
 146
 147/* prediv
 148 *
 149 * this divides the msysclk down to pass to h/p/etc.
 150 */
 151
 152static unsigned long s3c2443_prediv_getrate(struct clk *clk)
 153{
 154        unsigned long rate = clk_get_rate(clk->parent);
 155        unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
 156
 157        clkdiv0 &= S3C2443_CLKDIV0_PREDIV_MASK;
 158        clkdiv0 >>= S3C2443_CLKDIV0_PREDIV_SHIFT;
 159
 160        return rate / (clkdiv0 + 1);
 161}
 162
 163static struct clk clk_prediv = {
 164        .name           = "prediv",
 165        .parent         = &clk_msysclk.clk,
 166        .ops            = &(struct clk_ops) {
 167                .get_rate       = s3c2443_prediv_getrate,
 168        },
 169};
 170
 171/* hclk divider
 172 *
 173 * divides the prediv and provides the hclk.
 174 */
 175
 176static unsigned long s3c2443_hclkdiv_getrate(struct clk *clk)
 177{
 178        unsigned long rate = clk_get_rate(clk->parent);
 179        unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
 180
 181        clkdiv0 &= S3C2443_CLKDIV0_HCLKDIV_MASK;
 182
 183        return rate / (clkdiv0 + 1);
 184}
 185
 186static struct clk_ops clk_h_ops = {
 187        .get_rate       = s3c2443_hclkdiv_getrate,
 188};
 189
 190/* pclk divider
 191 *
 192 * divides the hclk and provides the pclk.
 193 */
 194
 195static unsigned long s3c2443_pclkdiv_getrate(struct clk *clk)
 196{
 197        unsigned long rate = clk_get_rate(clk->parent);
 198        unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
 199
 200        clkdiv0 = ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 1 : 0);
 201
 202        return rate / (clkdiv0 + 1);
 203}
 204
 205static struct clk_ops clk_p_ops = {
 206        .get_rate       = s3c2443_pclkdiv_getrate,
 207};
 208
 209/* armdiv
 210 *
 211 * this clock is sourced from msysclk and can have a number of
 212 * divider values applied to it to then be fed into armclk.
 213*/
 214
 215static unsigned int *armdiv;
 216static int nr_armdiv;
 217static int armdivmask;
 218
 219static unsigned long s3c2443_armclk_roundrate(struct clk *clk,
 220                                              unsigned long rate)
 221{
 222        unsigned long parent = clk_get_rate(clk->parent);
 223        unsigned long calc;
 224        unsigned best = 256; /* bigger than any value */
 225        unsigned div;
 226        int ptr;
 227
 228        if (!nr_armdiv)
 229                return -EINVAL;
 230
 231        for (ptr = 0; ptr < nr_armdiv; ptr++) {
 232                div = armdiv[ptr];
 233                if (div) {
 234                        /* cpufreq provides 266mhz as 266666000 not 266666666 */
 235                        calc = (parent / div / 1000) * 1000;
 236                        if (calc <= rate && div < best)
 237                                best = div;
 238                }
 239        }
 240
 241        return parent / best;
 242}
 243
 244static unsigned long s3c2443_armclk_getrate(struct clk *clk)
 245{
 246        unsigned long rate = clk_get_rate(clk->parent);
 247        unsigned long clkcon0;
 248        int val;
 249
 250        if (!nr_armdiv || !armdivmask)
 251                return -EINVAL;
 252
 253        clkcon0 = __raw_readl(S3C2443_CLKDIV0);
 254        clkcon0 &= armdivmask;
 255        val = clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT;
 256
 257        return rate / armdiv[val];
 258}
 259
 260static int s3c2443_armclk_setrate(struct clk *clk, unsigned long rate)
 261{
 262        unsigned long parent = clk_get_rate(clk->parent);
 263        unsigned long calc;
 264        unsigned div;
 265        unsigned best = 256; /* bigger than any value */
 266        int ptr;
 267        int val = -1;
 268
 269        if (!nr_armdiv || !armdivmask)
 270                return -EINVAL;
 271
 272        for (ptr = 0; ptr < nr_armdiv; ptr++) {
 273                div = armdiv[ptr];
 274                if (div) {
 275                        /* cpufreq provides 266mhz as 266666000 not 266666666 */
 276                        calc = (parent / div / 1000) * 1000;
 277                        if (calc <= rate && div < best) {
 278                                best = div;
 279                                val = ptr;
 280                        }
 281                }
 282        }
 283
 284        if (val >= 0) {
 285                unsigned long clkcon0;
 286
 287                clkcon0 = __raw_readl(S3C2443_CLKDIV0);
 288                clkcon0 &= ~armdivmask;
 289                clkcon0 |= val << S3C2443_CLKDIV0_ARMDIV_SHIFT;
 290                __raw_writel(clkcon0, S3C2443_CLKDIV0);
 291        }
 292
 293        return (val == -1) ? -EINVAL : 0;
 294}
 295
 296static struct clk clk_armdiv = {
 297        .name           = "armdiv",
 298        .parent         = &clk_msysclk.clk,
 299        .ops            = &(struct clk_ops) {
 300                .round_rate = s3c2443_armclk_roundrate,
 301                .get_rate = s3c2443_armclk_getrate,
 302                .set_rate = s3c2443_armclk_setrate,
 303        },
 304};
 305
 306/* armclk
 307 *
 308 * this is the clock fed into the ARM core itself, from armdiv or from hclk.
 309 */
 310
 311static struct clk *clk_arm_sources[] = {
 312        [0] = &clk_armdiv,
 313        [1] = &clk_h,
 314};
 315
 316static struct clksrc_clk clk_arm = {
 317        .clk    = {
 318                .name           = "armclk",
 319        },
 320        .sources = &(struct clksrc_sources) {
 321                .sources = clk_arm_sources,
 322                .nr_sources = ARRAY_SIZE(clk_arm_sources),
 323        },
 324        .reg_src = { .reg = S3C2443_CLKDIV0, .size = 1, .shift = 13 },
 325};
 326
 327/* usbhost
 328 *
 329 * usb host bus-clock, usually 48MHz to provide USB bus clock timing
 330*/
 331
 332static struct clksrc_clk clk_usb_bus_host = {
 333        .clk    = {
 334                .name           = "usb-bus-host-parent",
 335                .parent         = &clk_esysclk.clk,
 336                .ctrlbit        = S3C2443_SCLKCON_USBHOST,
 337                .enable         = s3c2443_clkcon_enable_s,
 338        },
 339        .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 },
 340};
 341
 342/* common clksrc clocks */
 343
 344static struct clksrc_clk clksrc_clks[] = {
 345        {
 346                /* camera interface bus-clock, divided down from esysclk */
 347                .clk    = {
 348                        .name           = "camif-upll", /* same as 2440 name */
 349                        .parent         = &clk_esysclk.clk,
 350                        .ctrlbit        = S3C2443_SCLKCON_CAMCLK,
 351                        .enable         = s3c2443_clkcon_enable_s,
 352                },
 353                .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 26 },
 354        }, {
 355                .clk    = {
 356                        .name           = "display-if",
 357                        .parent         = &clk_esysclk.clk,
 358                        .ctrlbit        = S3C2443_SCLKCON_DISPCLK,
 359                        .enable         = s3c2443_clkcon_enable_s,
 360                },
 361                .reg_div = { .reg = S3C2443_CLKDIV1, .size = 8, .shift = 16 },
 362        },
 363};
 364
 365static struct clksrc_clk clk_esys_uart = {
 366        /* ART baud-rate clock sourced from esysclk via a divisor */
 367        .clk    = {
 368                .name           = "uartclk",
 369                .parent         = &clk_esysclk.clk,
 370        },
 371        .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 },
 372};
 373
 374static struct clk clk_i2s_ext = {
 375        .name           = "i2s-ext",
 376};
 377
 378/* i2s_eplldiv
 379 *
 380 * This clock is the output from the I2S divisor of ESYSCLK, and is separate
 381 * from the mux that comes after it (cannot merge into one single clock)
 382*/
 383
 384static struct clksrc_clk clk_i2s_eplldiv = {
 385        .clk    = {
 386                .name           = "i2s-eplldiv",
 387                .parent         = &clk_esysclk.clk,
 388        },
 389        .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 12, },
 390};
 391
 392/* i2s-ref
 393 *
 394 * i2s bus reference clock, selectable from external, esysclk or epllref
 395 *
 396 * Note, this used to be two clocks, but was compressed into one.
 397*/
 398
 399static struct clk *clk_i2s_srclist[] = {
 400        [0] = &clk_i2s_eplldiv.clk,
 401        [1] = &clk_i2s_ext,
 402        [2] = &clk_epllref.clk,
 403        [3] = &clk_epllref.clk,
 404};
 405
 406static struct clksrc_clk clk_i2s = {
 407        .clk    = {
 408                .name           = "i2s-if",
 409                .ctrlbit        = S3C2443_SCLKCON_I2SCLK,
 410                .enable         = s3c2443_clkcon_enable_s,
 411
 412        },
 413        .sources = &(struct clksrc_sources) {
 414                .sources = clk_i2s_srclist,
 415                .nr_sources = ARRAY_SIZE(clk_i2s_srclist),
 416        },
 417        .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 14 },
 418};
 419
 420static struct clk init_clocks_off[] = {
 421        {
 422                .name           = "iis",
 423                .parent         = &clk_p,
 424                .enable         = s3c2443_clkcon_enable_p,
 425                .ctrlbit        = S3C2443_PCLKCON_IIS,
 426        }, {
 427                .name           = "adc",
 428                .parent         = &clk_p,
 429                .enable         = s3c2443_clkcon_enable_p,
 430                .ctrlbit        = S3C2443_PCLKCON_ADC,
 431        }, {
 432                .name           = "i2c",
 433                .parent         = &clk_p,
 434                .enable         = s3c2443_clkcon_enable_p,
 435                .ctrlbit        = S3C2443_PCLKCON_IIC,
 436        }
 437};
 438
 439static struct clk init_clocks[] = {
 440        {
 441                .name           = "dma",
 442                .parent         = &clk_h,
 443                .enable         = s3c2443_clkcon_enable_h,
 444                .ctrlbit        = S3C2443_HCLKCON_DMA0,
 445        }, {
 446                .name           = "dma",
 447                .parent         = &clk_h,
 448                .enable         = s3c2443_clkcon_enable_h,
 449                .ctrlbit        = S3C2443_HCLKCON_DMA1,
 450        }, {
 451                .name           = "dma",
 452                .parent         = &clk_h,
 453                .enable         = s3c2443_clkcon_enable_h,
 454                .ctrlbit        = S3C2443_HCLKCON_DMA2,
 455        }, {
 456                .name           = "dma",
 457                .parent         = &clk_h,
 458                .enable         = s3c2443_clkcon_enable_h,
 459                .ctrlbit        = S3C2443_HCLKCON_DMA3,
 460        }, {
 461                .name           = "dma",
 462                .parent         = &clk_h,
 463                .enable         = s3c2443_clkcon_enable_h,
 464                .ctrlbit        = S3C2443_HCLKCON_DMA4,
 465        }, {
 466                .name           = "dma",
 467                .parent         = &clk_h,
 468                .enable         = s3c2443_clkcon_enable_h,
 469                .ctrlbit        = S3C2443_HCLKCON_DMA5,
 470        }, {
 471                .name           = "gpio",
 472                .parent         = &clk_p,
 473                .enable         = s3c2443_clkcon_enable_p,
 474                .ctrlbit        = S3C2443_PCLKCON_GPIO,
 475        }, {
 476                .name           = "usb-host",
 477                .parent         = &clk_h,
 478                .enable         = s3c2443_clkcon_enable_h,
 479                .ctrlbit        = S3C2443_HCLKCON_USBH,
 480        }, {
 481                .name           = "usb-device",
 482                .parent         = &clk_h,
 483                .enable         = s3c2443_clkcon_enable_h,
 484                .ctrlbit        = S3C2443_HCLKCON_USBD,
 485        }, {
 486                .name           = "lcd",
 487                .parent         = &clk_h,
 488                .enable         = s3c2443_clkcon_enable_h,
 489                .ctrlbit        = S3C2443_HCLKCON_LCDC,
 490
 491        }, {
 492                .name           = "timers",
 493                .parent         = &clk_p,
 494                .enable         = s3c2443_clkcon_enable_p,
 495                .ctrlbit        = S3C2443_PCLKCON_PWMT,
 496        }, {
 497                .name           = "cfc",
 498                .parent         = &clk_h,
 499                .enable         = s3c2443_clkcon_enable_h,
 500                .ctrlbit        = S3C2443_HCLKCON_CFC,
 501        }, {
 502                .name           = "ssmc",
 503                .parent         = &clk_h,
 504                .enable         = s3c2443_clkcon_enable_h,
 505                .ctrlbit        = S3C2443_HCLKCON_SSMC,
 506        }, {
 507                .name           = "uart",
 508                .devname        = "s3c2440-uart.0",
 509                .parent         = &clk_p,
 510                .enable         = s3c2443_clkcon_enable_p,
 511                .ctrlbit        = S3C2443_PCLKCON_UART0,
 512        }, {
 513                .name           = "uart",
 514                .devname        = "s3c2440-uart.1",
 515                .parent         = &clk_p,
 516                .enable         = s3c2443_clkcon_enable_p,
 517                .ctrlbit        = S3C2443_PCLKCON_UART1,
 518        }, {
 519                .name           = "uart",
 520                .devname        = "s3c2440-uart.2",
 521                .parent         = &clk_p,
 522                .enable         = s3c2443_clkcon_enable_p,
 523                .ctrlbit        = S3C2443_PCLKCON_UART2,
 524        }, {
 525                .name           = "uart",
 526                .devname        = "s3c2440-uart.3",
 527                .parent         = &clk_p,
 528                .enable         = s3c2443_clkcon_enable_p,
 529                .ctrlbit        = S3C2443_PCLKCON_UART3,
 530        }, {
 531                .name           = "rtc",
 532                .parent         = &clk_p,
 533                .enable         = s3c2443_clkcon_enable_p,
 534                .ctrlbit        = S3C2443_PCLKCON_RTC,
 535        }, {
 536                .name           = "watchdog",
 537                .parent         = &clk_p,
 538                .ctrlbit        = S3C2443_PCLKCON_WDT,
 539        }, {
 540                .name           = "ac97",
 541                .parent         = &clk_p,
 542                .ctrlbit        = S3C2443_PCLKCON_AC97,
 543        }, {
 544                .name           = "nand",
 545                .parent         = &clk_h,
 546        }, {
 547                .name           = "usb-bus-host",
 548                .parent         = &clk_usb_bus_host.clk,
 549        }
 550};
 551
 552static struct clk hsmmc1_clk = {
 553        .name           = "hsmmc",
 554        .devname        = "s3c-sdhci.1",
 555        .parent         = &clk_h,
 556        .enable         = s3c2443_clkcon_enable_h,
 557        .ctrlbit        = S3C2443_HCLKCON_HSMMC,
 558};
 559
 560static struct clk hsspi_clk = {
 561        .name           = "spi",
 562        .devname        = "s3c2443-spi.0",
 563        .parent         = &clk_p,
 564        .enable         = s3c2443_clkcon_enable_p,
 565        .ctrlbit        = S3C2443_PCLKCON_HSSPI,
 566};
 567
 568/* EPLLCON compatible enough to get on/off information */
 569
 570void __init_or_cpufreq s3c2443_common_setup_clocks(pll_fn get_mpll)
 571{
 572        unsigned long epllcon = __raw_readl(S3C2443_EPLLCON);
 573        unsigned long mpllcon = __raw_readl(S3C2443_MPLLCON);
 574        struct clk *xtal_clk;
 575        unsigned long xtal;
 576        unsigned long pll;
 577        int ptr;
 578
 579        xtal_clk = clk_get(NULL, "xtal");
 580        xtal = clk_get_rate(xtal_clk);
 581        clk_put(xtal_clk);
 582
 583        pll = get_mpll(mpllcon, xtal);
 584        clk_msysclk.clk.rate = pll;
 585        clk_mpll.rate = pll;
 586
 587        printk("CPU: MPLL %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n",
 588               (mpllcon & S3C2443_PLLCON_OFF) ? "off" : "on",
 589               print_mhz(pll), print_mhz(clk_get_rate(&clk_armdiv)),
 590               print_mhz(clk_get_rate(&clk_h)),
 591               print_mhz(clk_get_rate(&clk_p)));
 592
 593        for (ptr = 0; ptr < ARRAY_SIZE(clksrc_clks); ptr++)
 594                s3c_set_clksrc(&clksrc_clks[ptr], true);
 595
 596        /* ensure usb bus clock is within correct rate of 48MHz */
 597
 598        if (clk_get_rate(&clk_usb_bus_host.clk) != (48 * 1000 * 1000)) {
 599                printk(KERN_INFO "Warning: USB host bus not at 48MHz\n");
 600                clk_set_rate(&clk_usb_bus_host.clk, 48*1000*1000);
 601        }
 602
 603        printk("CPU: EPLL %s %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n",
 604               (epllcon & S3C2443_PLLCON_OFF) ? "off" : "on",
 605               print_mhz(clk_get_rate(&clk_epll)),
 606               print_mhz(clk_get_rate(&clk_usb_bus)));
 607}
 608
 609static struct clk *clks[] __initdata = {
 610        &clk_prediv,
 611        &clk_mpllref,
 612        &clk_mdivclk,
 613        &clk_ext,
 614        &clk_epll,
 615        &clk_usb_bus,
 616        &clk_armdiv,
 617        &hsmmc1_clk,
 618        &hsspi_clk,
 619};
 620
 621static struct clksrc_clk *clksrcs[] __initdata = {
 622        &clk_i2s_eplldiv,
 623        &clk_i2s,
 624        &clk_usb_bus_host,
 625        &clk_epllref,
 626        &clk_esysclk,
 627        &clk_msysclk,
 628        &clk_arm,
 629};
 630
 631static struct clk_lookup s3c2443_clk_lookup[] = {
 632        CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
 633        CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
 634        CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_esys_uart.clk),
 635        CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.0", &hsmmc1_clk),
 636        CLKDEV_INIT("s3c2443-spi.0", "spi_busclk0", &hsspi_clk),
 637};
 638
 639void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
 640                                       unsigned int *divs, int nr_divs,
 641                                       int divmask)
 642{
 643        int ptr;
 644
 645        armdiv = divs;
 646        nr_armdiv = nr_divs;
 647        armdivmask = divmask;
 648
 649        /* s3c2443 parents h clock from prediv */
 650        clk_h.parent = &clk_prediv;
 651        clk_h.ops = &clk_h_ops;
 652
 653        /* and p clock from h clock */
 654        clk_p.parent = &clk_h;
 655        clk_p.ops = &clk_p_ops;
 656
 657        clk_usb_bus.parent = &clk_usb_bus_host.clk;
 658        clk_epll.parent = &clk_epllref.clk;
 659
 660        s3c24xx_register_baseclocks(xtal);
 661        s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
 662
 663        for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
 664                s3c_register_clksrc(clksrcs[ptr], 1);
 665
 666        s3c_register_clksrc(clksrc_clks, ARRAY_SIZE(clksrc_clks));
 667        s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
 668
 669        /* See s3c2443/etc notes on disabling clocks at init time */
 670        s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
 671        s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
 672        clkdev_add_table(s3c2443_clk_lookup, ARRAY_SIZE(s3c2443_clk_lookup));
 673
 674        s3c2443_common_setup_clocks(get_mpll);
 675}
 676