linux/drivers/clk/clk-prima2.c
<<
>>
Prefs
   1/*
   2 * Clock tree for CSR SiRFprimaII
   3 *
   4 * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
   5 *
   6 * Licensed under GPLv2 or later.
   7 */
   8
   9#include <linux/module.h>
  10#include <linux/bitops.h>
  11#include <linux/io.h>
  12#include <linux/clk.h>
  13#include <linux/clkdev.h>
  14#include <linux/clk-provider.h>
  15#include <linux/of_address.h>
  16#include <linux/syscore_ops.h>
  17
  18#define SIRFSOC_CLKC_CLK_EN0    0x0000
  19#define SIRFSOC_CLKC_CLK_EN1    0x0004
  20#define SIRFSOC_CLKC_REF_CFG    0x0014
  21#define SIRFSOC_CLKC_CPU_CFG    0x0018
  22#define SIRFSOC_CLKC_MEM_CFG    0x001c
  23#define SIRFSOC_CLKC_SYS_CFG    0x0020
  24#define SIRFSOC_CLKC_IO_CFG     0x0024
  25#define SIRFSOC_CLKC_DSP_CFG    0x0028
  26#define SIRFSOC_CLKC_GFX_CFG    0x002c
  27#define SIRFSOC_CLKC_MM_CFG     0x0030
  28#define SIRFSOC_CLKC_LCD_CFG     0x0034
  29#define SIRFSOC_CLKC_MMC_CFG    0x0038
  30#define SIRFSOC_CLKC_PLL1_CFG0  0x0040
  31#define SIRFSOC_CLKC_PLL2_CFG0  0x0044
  32#define SIRFSOC_CLKC_PLL3_CFG0  0x0048
  33#define SIRFSOC_CLKC_PLL1_CFG1  0x004c
  34#define SIRFSOC_CLKC_PLL2_CFG1  0x0050
  35#define SIRFSOC_CLKC_PLL3_CFG1  0x0054
  36#define SIRFSOC_CLKC_PLL1_CFG2  0x0058
  37#define SIRFSOC_CLKC_PLL2_CFG2  0x005c
  38#define SIRFSOC_CLKC_PLL3_CFG2  0x0060
  39#define SIRFSOC_USBPHY_PLL_CTRL 0x0008
  40#define SIRFSOC_USBPHY_PLL_POWERDOWN  BIT(1)
  41#define SIRFSOC_USBPHY_PLL_BYPASS     BIT(2)
  42#define SIRFSOC_USBPHY_PLL_LOCK       BIT(3)
  43
  44static void *sirfsoc_clk_vbase, *sirfsoc_rsc_vbase;
  45
  46#define KHZ     1000
  47#define MHZ     (KHZ * KHZ)
  48
  49/*
  50 * SiRFprimaII clock controller
  51 * - 2 oscillators: osc-26MHz, rtc-32.768KHz
  52 * - 3 standard configurable plls: pll1, pll2 & pll3
  53 * - 2 exclusive plls: usb phy pll and sata phy pll
  54 * - 8 clock domains: cpu/cpudiv, mem/memdiv, sys/io, dsp, graphic, multimedia,
  55 *     display and sdphy.
  56 *     Each clock domain can select its own clock source from five clock sources,
  57 *     X_XIN, X_XINW, PLL1, PLL2 and PLL3. The domain clock is used as the source
  58 *     clock of the group clock.
  59 *     - dsp domain: gps, mf
  60 *     - io domain: dmac, nand, audio, uart, i2c, spi, usp, pwm, pulse
  61 *     - sys domain: security
  62 */
  63
  64struct clk_pll {
  65        struct clk_hw hw;
  66        unsigned short regofs;  /* register offset */
  67};
  68
  69#define to_pllclk(_hw) container_of(_hw, struct clk_pll, hw)
  70
  71struct clk_dmn {
  72        struct clk_hw hw;
  73        signed char enable_bit; /* enable bit: 0 ~ 63 */
  74        unsigned short regofs;  /* register offset */
  75};
  76
  77#define to_dmnclk(_hw) container_of(_hw, struct clk_dmn, hw)
  78
  79struct clk_std {
  80        struct clk_hw hw;
  81        signed char enable_bit; /* enable bit: 0 ~ 63 */
  82};
  83
  84#define to_stdclk(_hw) container_of(_hw, struct clk_std, hw)
  85
  86static int std_clk_is_enabled(struct clk_hw *hw);
  87static int std_clk_enable(struct clk_hw *hw);
  88static void std_clk_disable(struct clk_hw *hw);
  89
  90static inline unsigned long clkc_readl(unsigned reg)
  91{
  92        return readl(sirfsoc_clk_vbase + reg);
  93}
  94
  95static inline void clkc_writel(u32 val, unsigned reg)
  96{
  97        writel(val, sirfsoc_clk_vbase + reg);
  98}
  99
 100/*
 101 * std pll
 102 */
 103
 104static unsigned long pll_clk_recalc_rate(struct clk_hw *hw,
 105        unsigned long parent_rate)
 106{
 107        unsigned long fin = parent_rate;
 108        struct clk_pll *clk = to_pllclk(hw);
 109        u32 regcfg2 = clk->regofs + SIRFSOC_CLKC_PLL1_CFG2 -
 110                SIRFSOC_CLKC_PLL1_CFG0;
 111
 112        if (clkc_readl(regcfg2) & BIT(2)) {
 113                /* pll bypass mode */
 114                return fin;
 115        } else {
 116                /* fout = fin * nf / nr / od */
 117                u32 cfg0 = clkc_readl(clk->regofs);
 118                u32 nf = (cfg0 & (BIT(13) - 1)) + 1;
 119                u32 nr = ((cfg0 >> 13) & (BIT(6) - 1)) + 1;
 120                u32 od = ((cfg0 >> 19) & (BIT(4) - 1)) + 1;
 121                WARN_ON(fin % MHZ);
 122                return fin / MHZ * nf / nr / od * MHZ;
 123        }
 124}
 125
 126static long pll_clk_round_rate(struct clk_hw *hw, unsigned long rate,
 127        unsigned long *parent_rate)
 128{
 129        unsigned long fin, nf, nr, od;
 130
 131        /*
 132         * fout = fin * nf / (nr * od);
 133         * set od = 1, nr = fin/MHz, so fout = nf * MHz
 134         */
 135        rate = rate - rate % MHZ;
 136
 137        nf = rate / MHZ;
 138        if (nf > BIT(13))
 139                nf = BIT(13);
 140        if (nf < 1)
 141                nf = 1;
 142
 143        fin = *parent_rate;
 144
 145        nr = fin / MHZ;
 146        if (nr > BIT(6))
 147                nr = BIT(6);
 148        od = 1;
 149
 150        return fin * nf / (nr * od);
 151}
 152
 153static int pll_clk_set_rate(struct clk_hw *hw, unsigned long rate,
 154        unsigned long parent_rate)
 155{
 156        struct clk_pll *clk = to_pllclk(hw);
 157        unsigned long fin, nf, nr, od, reg;
 158
 159        /*
 160         * fout = fin * nf / (nr * od);
 161         * set od = 1, nr = fin/MHz, so fout = nf * MHz
 162         */
 163
 164        nf = rate / MHZ;
 165        if (unlikely((rate % MHZ) || nf > BIT(13) || nf < 1))
 166                return -EINVAL;
 167
 168        fin = parent_rate;
 169        BUG_ON(fin < MHZ);
 170
 171        nr = fin / MHZ;
 172        BUG_ON((fin % MHZ) || nr > BIT(6));
 173
 174        od = 1;
 175
 176        reg = (nf - 1) | ((nr - 1) << 13) | ((od - 1) << 19);
 177        clkc_writel(reg, clk->regofs);
 178
 179        reg = clk->regofs + SIRFSOC_CLKC_PLL1_CFG1 - SIRFSOC_CLKC_PLL1_CFG0;
 180        clkc_writel((nf >> 1) - 1, reg);
 181
 182        reg = clk->regofs + SIRFSOC_CLKC_PLL1_CFG2 - SIRFSOC_CLKC_PLL1_CFG0;
 183        while (!(clkc_readl(reg) & BIT(6)))
 184                cpu_relax();
 185
 186        return 0;
 187}
 188
 189static struct clk_ops std_pll_ops = {
 190        .recalc_rate = pll_clk_recalc_rate,
 191        .round_rate = pll_clk_round_rate,
 192        .set_rate = pll_clk_set_rate,
 193};
 194
 195static const char *pll_clk_parents[] = {
 196        "osc",
 197};
 198
 199static struct clk_init_data clk_pll1_init = {
 200        .name = "pll1",
 201        .ops = &std_pll_ops,
 202        .parent_names = pll_clk_parents,
 203        .num_parents = ARRAY_SIZE(pll_clk_parents),
 204};
 205
 206static struct clk_init_data clk_pll2_init = {
 207        .name = "pll2",
 208        .ops = &std_pll_ops,
 209        .parent_names = pll_clk_parents,
 210        .num_parents = ARRAY_SIZE(pll_clk_parents),
 211};
 212
 213static struct clk_init_data clk_pll3_init = {
 214        .name = "pll3",
 215        .ops = &std_pll_ops,
 216        .parent_names = pll_clk_parents,
 217        .num_parents = ARRAY_SIZE(pll_clk_parents),
 218};
 219
 220static struct clk_pll clk_pll1 = {
 221        .regofs = SIRFSOC_CLKC_PLL1_CFG0,
 222        .hw = {
 223                .init = &clk_pll1_init,
 224        },
 225};
 226
 227static struct clk_pll clk_pll2 = {
 228        .regofs = SIRFSOC_CLKC_PLL2_CFG0,
 229        .hw = {
 230                .init = &clk_pll2_init,
 231        },
 232};
 233
 234static struct clk_pll clk_pll3 = {
 235        .regofs = SIRFSOC_CLKC_PLL3_CFG0,
 236        .hw = {
 237                .init = &clk_pll3_init,
 238        },
 239};
 240
 241/*
 242 * usb uses specified pll
 243 */
 244
 245static int usb_pll_clk_enable(struct clk_hw *hw)
 246{
 247        u32 reg = readl(sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL);
 248        reg &= ~(SIRFSOC_USBPHY_PLL_POWERDOWN | SIRFSOC_USBPHY_PLL_BYPASS);
 249        writel(reg, sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL);
 250        while (!(readl(sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL) &
 251                        SIRFSOC_USBPHY_PLL_LOCK))
 252                cpu_relax();
 253
 254        return 0;
 255}
 256
 257static void usb_pll_clk_disable(struct clk_hw *clk)
 258{
 259        u32 reg = readl(sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL);
 260        reg |= (SIRFSOC_USBPHY_PLL_POWERDOWN | SIRFSOC_USBPHY_PLL_BYPASS);
 261        writel(reg, sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL);
 262}
 263
 264static unsigned long usb_pll_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
 265{
 266        u32 reg = readl(sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL);
 267        return (reg & SIRFSOC_USBPHY_PLL_BYPASS) ? parent_rate : 48*MHZ;
 268}
 269
 270static struct clk_ops usb_pll_ops = {
 271        .enable = usb_pll_clk_enable,
 272        .disable = usb_pll_clk_disable,
 273        .recalc_rate = usb_pll_clk_recalc_rate,
 274};
 275
 276static struct clk_init_data clk_usb_pll_init = {
 277        .name = "usb_pll",
 278        .ops = &usb_pll_ops,
 279        .parent_names = pll_clk_parents,
 280        .num_parents = ARRAY_SIZE(pll_clk_parents),
 281};
 282
 283static struct clk_hw usb_pll_clk_hw = {
 284        .init = &clk_usb_pll_init,
 285};
 286
 287/*
 288 * clock domains - cpu, mem, sys/io, dsp, gfx
 289 */
 290
 291static const char *dmn_clk_parents[] = {
 292        "rtc",
 293        "osc",
 294        "pll1",
 295        "pll2",
 296        "pll3",
 297};
 298
 299static u8 dmn_clk_get_parent(struct clk_hw *hw)
 300{
 301        struct clk_dmn *clk = to_dmnclk(hw);
 302        u32 cfg = clkc_readl(clk->regofs);
 303
 304        /* parent of io domain can only be pll3 */
 305        if (strcmp(hw->init->name, "io") == 0)
 306                return 4;
 307
 308        WARN_ON((cfg & (BIT(3) - 1)) > 4);
 309
 310        return cfg & (BIT(3) - 1);
 311}
 312
 313static int dmn_clk_set_parent(struct clk_hw *hw, u8 parent)
 314{
 315        struct clk_dmn *clk = to_dmnclk(hw);
 316        u32 cfg = clkc_readl(clk->regofs);
 317
 318        /* parent of io domain can only be pll3 */
 319        if (strcmp(hw->init->name, "io") == 0)
 320                return -EINVAL;
 321
 322        cfg &= ~(BIT(3) - 1);
 323        clkc_writel(cfg | parent, clk->regofs);
 324        /* BIT(3) - switching status: 1 - busy, 0 - done */
 325        while (clkc_readl(clk->regofs) & BIT(3))
 326                cpu_relax();
 327
 328        return 0;
 329}
 330
 331static unsigned long dmn_clk_recalc_rate(struct clk_hw *hw,
 332        unsigned long parent_rate)
 333
 334{
 335        unsigned long fin = parent_rate;
 336        struct clk_dmn *clk = to_dmnclk(hw);
 337
 338        u32 cfg = clkc_readl(clk->regofs);
 339
 340        if (cfg & BIT(24)) {
 341                /* fcd bypass mode */
 342                return fin;
 343        } else {
 344                /*
 345                 * wait count: bit[19:16], hold count: bit[23:20]
 346                 */
 347                u32 wait = (cfg >> 16) & (BIT(4) - 1);
 348                u32 hold = (cfg >> 20) & (BIT(4) - 1);
 349
 350                return fin / (wait + hold + 2);
 351        }
 352}
 353
 354static long dmn_clk_round_rate(struct clk_hw *hw, unsigned long rate,
 355        unsigned long *parent_rate)
 356{
 357        unsigned long fin;
 358        unsigned ratio, wait, hold;
 359        unsigned bits = (strcmp(hw->init->name, "mem") == 0) ? 3 : 4;
 360
 361        fin = *parent_rate;
 362        ratio = fin / rate;
 363
 364        if (ratio < 2)
 365                ratio = 2;
 366        if (ratio > BIT(bits + 1))
 367                ratio = BIT(bits + 1);
 368
 369        wait = (ratio >> 1) - 1;
 370        hold = ratio - wait - 2;
 371
 372        return fin / (wait + hold + 2);
 373}
 374
 375static int dmn_clk_set_rate(struct clk_hw *hw, unsigned long rate,
 376        unsigned long parent_rate)
 377{
 378        struct clk_dmn *clk = to_dmnclk(hw);
 379        unsigned long fin;
 380        unsigned ratio, wait, hold, reg;
 381        unsigned bits = (strcmp(hw->init->name, "mem") == 0) ? 3 : 4;
 382
 383        fin = parent_rate;
 384        ratio = fin / rate;
 385
 386        if (unlikely(ratio < 2 || ratio > BIT(bits + 1)))
 387                return -EINVAL;
 388
 389        WARN_ON(fin % rate);
 390
 391        wait = (ratio >> 1) - 1;
 392        hold = ratio - wait - 2;
 393
 394        reg = clkc_readl(clk->regofs);
 395        reg &= ~(((BIT(bits) - 1) << 16) | ((BIT(bits) - 1) << 20));
 396        reg |= (wait << 16) | (hold << 20) | BIT(25);
 397        clkc_writel(reg, clk->regofs);
 398
 399        /* waiting FCD been effective */
 400        while (clkc_readl(clk->regofs) & BIT(25))
 401                cpu_relax();
 402
 403        return 0;
 404}
 405
 406static struct clk_ops msi_ops = {
 407        .set_rate = dmn_clk_set_rate,
 408        .round_rate = dmn_clk_round_rate,
 409        .recalc_rate = dmn_clk_recalc_rate,
 410        .set_parent = dmn_clk_set_parent,
 411        .get_parent = dmn_clk_get_parent,
 412};
 413
 414static struct clk_init_data clk_mem_init = {
 415        .name = "mem",
 416        .ops = &msi_ops,
 417        .parent_names = dmn_clk_parents,
 418        .num_parents = ARRAY_SIZE(dmn_clk_parents),
 419};
 420
 421static struct clk_dmn clk_mem = {
 422        .regofs = SIRFSOC_CLKC_MEM_CFG,
 423        .hw = {
 424                .init = &clk_mem_init,
 425        },
 426};
 427
 428static struct clk_init_data clk_sys_init = {
 429        .name = "sys",
 430        .ops = &msi_ops,
 431        .parent_names = dmn_clk_parents,
 432        .num_parents = ARRAY_SIZE(dmn_clk_parents),
 433        .flags = CLK_SET_RATE_GATE,
 434};
 435
 436static struct clk_dmn clk_sys = {
 437        .regofs = SIRFSOC_CLKC_SYS_CFG,
 438        .hw = {
 439                .init = &clk_sys_init,
 440        },
 441};
 442
 443static struct clk_init_data clk_io_init = {
 444        .name = "io",
 445        .ops = &msi_ops,
 446        .parent_names = dmn_clk_parents,
 447        .num_parents = ARRAY_SIZE(dmn_clk_parents),
 448};
 449
 450static struct clk_dmn clk_io = {
 451        .regofs = SIRFSOC_CLKC_IO_CFG,
 452        .hw = {
 453                .init = &clk_io_init,
 454        },
 455};
 456
 457static struct clk_ops cpu_ops = {
 458        .set_parent = dmn_clk_set_parent,
 459        .get_parent = dmn_clk_get_parent,
 460};
 461
 462static struct clk_init_data clk_cpu_init = {
 463        .name = "cpu",
 464        .ops = &cpu_ops,
 465        .parent_names = dmn_clk_parents,
 466        .num_parents = ARRAY_SIZE(dmn_clk_parents),
 467        .flags = CLK_SET_RATE_PARENT,
 468};
 469
 470static struct clk_dmn clk_cpu = {
 471        .regofs = SIRFSOC_CLKC_CPU_CFG,
 472        .hw = {
 473                .init = &clk_cpu_init,
 474        },
 475};
 476
 477static struct clk_ops dmn_ops = {
 478        .is_enabled = std_clk_is_enabled,
 479        .enable = std_clk_enable,
 480        .disable = std_clk_disable,
 481        .set_rate = dmn_clk_set_rate,
 482        .round_rate = dmn_clk_round_rate,
 483        .recalc_rate = dmn_clk_recalc_rate,
 484        .set_parent = dmn_clk_set_parent,
 485        .get_parent = dmn_clk_get_parent,
 486};
 487
 488/* dsp, gfx, mm, lcd and vpp domain */
 489
 490static struct clk_init_data clk_dsp_init = {
 491        .name = "dsp",
 492        .ops = &dmn_ops,
 493        .parent_names = dmn_clk_parents,
 494        .num_parents = ARRAY_SIZE(dmn_clk_parents),
 495};
 496
 497static struct clk_dmn clk_dsp = {
 498        .regofs = SIRFSOC_CLKC_DSP_CFG,
 499        .enable_bit = 0,
 500        .hw = {
 501                .init = &clk_dsp_init,
 502        },
 503};
 504
 505static struct clk_init_data clk_gfx_init = {
 506        .name = "gfx",
 507        .ops = &dmn_ops,
 508        .parent_names = dmn_clk_parents,
 509        .num_parents = ARRAY_SIZE(dmn_clk_parents),
 510};
 511
 512static struct clk_dmn clk_gfx = {
 513        .regofs = SIRFSOC_CLKC_GFX_CFG,
 514        .enable_bit = 8,
 515        .hw = {
 516                .init = &clk_gfx_init,
 517        },
 518};
 519
 520static struct clk_init_data clk_mm_init = {
 521        .name = "mm",
 522        .ops = &dmn_ops,
 523        .parent_names = dmn_clk_parents,
 524        .num_parents = ARRAY_SIZE(dmn_clk_parents),
 525};
 526
 527static struct clk_dmn clk_mm = {
 528        .regofs = SIRFSOC_CLKC_MM_CFG,
 529        .enable_bit = 9,
 530        .hw = {
 531                .init = &clk_mm_init,
 532        },
 533};
 534
 535static struct clk_init_data clk_lcd_init = {
 536        .name = "lcd",
 537        .ops = &dmn_ops,
 538        .parent_names = dmn_clk_parents,
 539        .num_parents = ARRAY_SIZE(dmn_clk_parents),
 540};
 541
 542static struct clk_dmn clk_lcd = {
 543        .regofs = SIRFSOC_CLKC_LCD_CFG,
 544        .enable_bit = 10,
 545        .hw = {
 546                .init = &clk_lcd_init,
 547        },
 548};
 549
 550static struct clk_init_data clk_vpp_init = {
 551        .name = "vpp",
 552        .ops = &dmn_ops,
 553        .parent_names = dmn_clk_parents,
 554        .num_parents = ARRAY_SIZE(dmn_clk_parents),
 555};
 556
 557static struct clk_dmn clk_vpp = {
 558        .regofs = SIRFSOC_CLKC_LCD_CFG,
 559        .enable_bit = 11,
 560        .hw = {
 561                .init = &clk_vpp_init,
 562        },
 563};
 564
 565static struct clk_init_data clk_mmc01_init = {
 566        .name = "mmc01",
 567        .ops = &dmn_ops,
 568        .parent_names = dmn_clk_parents,
 569        .num_parents = ARRAY_SIZE(dmn_clk_parents),
 570};
 571
 572static struct clk_dmn clk_mmc01 = {
 573        .regofs = SIRFSOC_CLKC_MMC_CFG,
 574        .enable_bit = 59,
 575        .hw = {
 576                .init = &clk_mmc01_init,
 577        },
 578};
 579
 580static struct clk_init_data clk_mmc23_init = {
 581        .name = "mmc23",
 582        .ops = &dmn_ops,
 583        .parent_names = dmn_clk_parents,
 584        .num_parents = ARRAY_SIZE(dmn_clk_parents),
 585};
 586
 587static struct clk_dmn clk_mmc23 = {
 588        .regofs = SIRFSOC_CLKC_MMC_CFG,
 589        .enable_bit = 60,
 590        .hw = {
 591                .init = &clk_mmc23_init,
 592        },
 593};
 594
 595static struct clk_init_data clk_mmc45_init = {
 596        .name = "mmc45",
 597        .ops = &dmn_ops,
 598        .parent_names = dmn_clk_parents,
 599        .num_parents = ARRAY_SIZE(dmn_clk_parents),
 600};
 601
 602static struct clk_dmn clk_mmc45 = {
 603        .regofs = SIRFSOC_CLKC_MMC_CFG,
 604        .enable_bit = 61,
 605        .hw = {
 606                .init = &clk_mmc45_init,
 607        },
 608};
 609
 610/*
 611 * peripheral controllers in io domain
 612 */
 613
 614static int std_clk_is_enabled(struct clk_hw *hw)
 615{
 616        u32 reg;
 617        int bit;
 618        struct clk_std *clk = to_stdclk(hw);
 619
 620        bit = clk->enable_bit % 32;
 621        reg = clk->enable_bit / 32;
 622        reg = SIRFSOC_CLKC_CLK_EN0 + reg * sizeof(reg);
 623
 624        return !!(clkc_readl(reg) & BIT(bit));
 625}
 626
 627static int std_clk_enable(struct clk_hw *hw)
 628{
 629        u32 val, reg;
 630        int bit;
 631        struct clk_std *clk = to_stdclk(hw);
 632
 633        BUG_ON(clk->enable_bit < 0 || clk->enable_bit > 63);
 634
 635        bit = clk->enable_bit % 32;
 636        reg = clk->enable_bit / 32;
 637        reg = SIRFSOC_CLKC_CLK_EN0 + reg * sizeof(reg);
 638
 639        val = clkc_readl(reg) | BIT(bit);
 640        clkc_writel(val, reg);
 641        return 0;
 642}
 643
 644static void std_clk_disable(struct clk_hw *hw)
 645{
 646        u32 val, reg;
 647        int bit;
 648        struct clk_std *clk = to_stdclk(hw);
 649
 650        BUG_ON(clk->enable_bit < 0 || clk->enable_bit > 63);
 651
 652        bit = clk->enable_bit % 32;
 653        reg = clk->enable_bit / 32;
 654        reg = SIRFSOC_CLKC_CLK_EN0 + reg * sizeof(reg);
 655
 656        val = clkc_readl(reg) & ~BIT(bit);
 657        clkc_writel(val, reg);
 658}
 659
 660static const char *std_clk_io_parents[] = {
 661        "io",
 662};
 663
 664static struct clk_ops ios_ops = {
 665        .is_enabled = std_clk_is_enabled,
 666        .enable = std_clk_enable,
 667        .disable = std_clk_disable,
 668};
 669
 670static struct clk_init_data clk_dmac0_init = {
 671        .name = "dmac0",
 672        .ops = &ios_ops,
 673        .parent_names = std_clk_io_parents,
 674        .num_parents = ARRAY_SIZE(std_clk_io_parents),
 675};
 676
 677static struct clk_std clk_dmac0 = {
 678        .enable_bit = 32,
 679        .hw = {
 680                .init = &clk_dmac0_init,
 681        },
 682};
 683
 684static struct clk_init_data clk_dmac1_init = {
 685        .name = "dmac1",
 686        .ops = &ios_ops,
 687        .parent_names = std_clk_io_parents,
 688        .num_parents = ARRAY_SIZE(std_clk_io_parents),
 689};
 690
 691static struct clk_std clk_dmac1 = {
 692        .enable_bit = 33,
 693        .hw = {
 694                .init = &clk_dmac1_init,
 695        },
 696};
 697
 698static struct clk_init_data clk_nand_init = {
 699        .name = "nand",
 700        .ops = &ios_ops,
 701        .parent_names = std_clk_io_parents,
 702        .num_parents = ARRAY_SIZE(std_clk_io_parents),
 703};
 704
 705static struct clk_std clk_nand = {
 706        .enable_bit = 34,
 707        .hw = {
 708                .init = &clk_nand_init,
 709        },
 710};
 711
 712static struct clk_init_data clk_audio_init = {
 713        .name = "audio",
 714        .ops = &ios_ops,
 715        .parent_names = std_clk_io_parents,
 716        .num_parents = ARRAY_SIZE(std_clk_io_parents),
 717};
 718
 719static struct clk_std clk_audio = {
 720        .enable_bit = 35,
 721        .hw = {
 722                .init = &clk_audio_init,
 723        },
 724};
 725
 726static struct clk_init_data clk_uart0_init = {
 727        .name = "uart0",
 728        .ops = &ios_ops,
 729        .parent_names = std_clk_io_parents,
 730        .num_parents = ARRAY_SIZE(std_clk_io_parents),
 731};
 732
 733static struct clk_std clk_uart0 = {
 734        .enable_bit = 36,
 735        .hw = {
 736                .init = &clk_uart0_init,
 737        },
 738};
 739
 740static struct clk_init_data clk_uart1_init = {
 741        .name = "uart1",
 742        .ops = &ios_ops,
 743        .parent_names = std_clk_io_parents,
 744        .num_parents = ARRAY_SIZE(std_clk_io_parents),
 745};
 746
 747static struct clk_std clk_uart1 = {
 748        .enable_bit = 37,
 749        .hw = {
 750                .init = &clk_uart1_init,
 751        },
 752};
 753
 754static struct clk_init_data clk_uart2_init = {
 755        .name = "uart2",
 756        .ops = &ios_ops,
 757        .parent_names = std_clk_io_parents,
 758        .num_parents = ARRAY_SIZE(std_clk_io_parents),
 759};
 760
 761static struct clk_std clk_uart2 = {
 762        .enable_bit = 38,
 763        .hw = {
 764                .init = &clk_uart2_init,
 765        },
 766};
 767
 768static struct clk_init_data clk_usp0_init = {
 769        .name = "usp0",
 770        .ops = &ios_ops,
 771        .parent_names = std_clk_io_parents,
 772        .num_parents = ARRAY_SIZE(std_clk_io_parents),
 773};
 774
 775static struct clk_std clk_usp0 = {
 776        .enable_bit = 39,
 777        .hw = {
 778                .init = &clk_usp0_init,
 779        },
 780};
 781
 782static struct clk_init_data clk_usp1_init = {
 783        .name = "usp1",
 784        .ops = &ios_ops,
 785        .parent_names = std_clk_io_parents,
 786        .num_parents = ARRAY_SIZE(std_clk_io_parents),
 787};
 788
 789static struct clk_std clk_usp1 = {
 790        .enable_bit = 40,
 791        .hw = {
 792                .init = &clk_usp1_init,
 793        },
 794};
 795
 796static struct clk_init_data clk_usp2_init = {
 797        .name = "usp2",
 798        .ops = &ios_ops,
 799        .parent_names = std_clk_io_parents,
 800        .num_parents = ARRAY_SIZE(std_clk_io_parents),
 801};
 802
 803static struct clk_std clk_usp2 = {
 804        .enable_bit = 41,
 805        .hw = {
 806                .init = &clk_usp2_init,
 807        },
 808};
 809
 810static struct clk_init_data clk_vip_init = {
 811        .name = "vip",
 812        .ops = &ios_ops,
 813        .parent_names = std_clk_io_parents,
 814        .num_parents = ARRAY_SIZE(std_clk_io_parents),
 815};
 816
 817static struct clk_std clk_vip = {
 818        .enable_bit = 42,
 819        .hw = {
 820                .init = &clk_vip_init,
 821        },
 822};
 823
 824static struct clk_init_data clk_spi0_init = {
 825        .name = "spi0",
 826        .ops = &ios_ops,
 827        .parent_names = std_clk_io_parents,
 828        .num_parents = ARRAY_SIZE(std_clk_io_parents),
 829};
 830
 831static struct clk_std clk_spi0 = {
 832        .enable_bit = 43,
 833        .hw = {
 834                .init = &clk_spi0_init,
 835        },
 836};
 837
 838static struct clk_init_data clk_spi1_init = {
 839        .name = "spi1",
 840        .ops = &ios_ops,
 841        .parent_names = std_clk_io_parents,
 842        .num_parents = ARRAY_SIZE(std_clk_io_parents),
 843};
 844
 845static struct clk_std clk_spi1 = {
 846        .enable_bit = 44,
 847        .hw = {
 848                .init = &clk_spi1_init,
 849        },
 850};
 851
 852static struct clk_init_data clk_tsc_init = {
 853        .name = "tsc",
 854        .ops = &ios_ops,
 855        .parent_names = std_clk_io_parents,
 856        .num_parents = ARRAY_SIZE(std_clk_io_parents),
 857};
 858
 859static struct clk_std clk_tsc = {
 860        .enable_bit = 45,
 861        .hw = {
 862                .init = &clk_tsc_init,
 863        },
 864};
 865
 866static struct clk_init_data clk_i2c0_init = {
 867        .name = "i2c0",
 868        .ops = &ios_ops,
 869        .parent_names = std_clk_io_parents,
 870        .num_parents = ARRAY_SIZE(std_clk_io_parents),
 871};
 872
 873static struct clk_std clk_i2c0 = {
 874        .enable_bit = 46,
 875        .hw = {
 876                .init = &clk_i2c0_init,
 877        },
 878};
 879
 880static struct clk_init_data clk_i2c1_init = {
 881        .name = "i2c1",
 882        .ops = &ios_ops,
 883        .parent_names = std_clk_io_parents,
 884        .num_parents = ARRAY_SIZE(std_clk_io_parents),
 885};
 886
 887static struct clk_std clk_i2c1 = {
 888        .enable_bit = 47,
 889        .hw = {
 890                .init = &clk_i2c1_init,
 891        },
 892};
 893
 894static struct clk_init_data clk_pwmc_init = {
 895        .name = "pwmc",
 896        .ops = &ios_ops,
 897        .parent_names = std_clk_io_parents,
 898        .num_parents = ARRAY_SIZE(std_clk_io_parents),
 899};
 900
 901static struct clk_std clk_pwmc = {
 902        .enable_bit = 48,
 903        .hw = {
 904                .init = &clk_pwmc_init,
 905        },
 906};
 907
 908static struct clk_init_data clk_efuse_init = {
 909        .name = "efuse",
 910        .ops = &ios_ops,
 911        .parent_names = std_clk_io_parents,
 912        .num_parents = ARRAY_SIZE(std_clk_io_parents),
 913};
 914
 915static struct clk_std clk_efuse = {
 916        .enable_bit = 49,
 917        .hw = {
 918                .init = &clk_efuse_init,
 919        },
 920};
 921
 922static struct clk_init_data clk_pulse_init = {
 923        .name = "pulse",
 924        .ops = &ios_ops,
 925        .parent_names = std_clk_io_parents,
 926        .num_parents = ARRAY_SIZE(std_clk_io_parents),
 927};
 928
 929static struct clk_std clk_pulse = {
 930        .enable_bit = 50,
 931        .hw = {
 932                .init = &clk_pulse_init,
 933        },
 934};
 935
 936static const char *std_clk_dsp_parents[] = {
 937        "dsp",
 938};
 939
 940static struct clk_init_data clk_gps_init = {
 941        .name = "gps",
 942        .ops = &ios_ops,
 943        .parent_names = std_clk_dsp_parents,
 944        .num_parents = ARRAY_SIZE(std_clk_dsp_parents),
 945};
 946
 947static struct clk_std clk_gps = {
 948        .enable_bit = 1,
 949        .hw = {
 950                .init = &clk_gps_init,
 951        },
 952};
 953
 954static struct clk_init_data clk_mf_init = {
 955        .name = "mf",
 956        .ops = &ios_ops,
 957        .parent_names = std_clk_io_parents,
 958        .num_parents = ARRAY_SIZE(std_clk_io_parents),
 959};
 960
 961static struct clk_std clk_mf = {
 962        .enable_bit = 2,
 963        .hw = {
 964                .init = &clk_mf_init,
 965        },
 966};
 967
 968static const char *std_clk_sys_parents[] = {
 969        "sys",
 970};
 971
 972static struct clk_init_data clk_security_init = {
 973        .name = "mf",
 974        .ops = &ios_ops,
 975        .parent_names = std_clk_sys_parents,
 976        .num_parents = ARRAY_SIZE(std_clk_sys_parents),
 977};
 978
 979static struct clk_std clk_security = {
 980        .enable_bit = 19,
 981        .hw = {
 982                .init = &clk_security_init,
 983        },
 984};
 985
 986static const char *std_clk_usb_parents[] = {
 987        "usb_pll",
 988};
 989
 990static struct clk_init_data clk_usb0_init = {
 991        .name = "usb0",
 992        .ops = &ios_ops,
 993        .parent_names = std_clk_usb_parents,
 994        .num_parents = ARRAY_SIZE(std_clk_usb_parents),
 995};
 996
 997static struct clk_std clk_usb0 = {
 998        .enable_bit = 16,
 999        .hw = {
1000                .init = &clk_usb0_init,
1001        },
1002};
1003
1004static struct clk_init_data clk_usb1_init = {
1005        .name = "usb1",
1006        .ops = &ios_ops,
1007        .parent_names = std_clk_usb_parents,
1008        .num_parents = ARRAY_SIZE(std_clk_usb_parents),
1009};
1010
1011static struct clk_std clk_usb1 = {
1012        .enable_bit = 17,
1013        .hw = {
1014                .init = &clk_usb1_init,
1015        },
1016};
1017
1018static struct of_device_id clkc_ids[] = {
1019        { .compatible = "sirf,prima2-clkc" },
1020        {},
1021};
1022
1023static struct of_device_id rsc_ids[] = {
1024        { .compatible = "sirf,prima2-rsc" },
1025        {},
1026};
1027
1028enum prima2_clk_index {
1029        /* 0    1     2      3      4      5      6       7         8      9 */
1030        rtc,    osc,   pll1,  pll2,  pll3,  mem,   sys,   security, dsp,   gps,
1031        mf,     io,    cpu,   uart0, uart1, uart2, tsc,   i2c0,     i2c1,  spi0,
1032        spi1,   pwmc,  efuse, pulse, dmac0, dmac1, nand,  audio,    usp0,  usp1,
1033        usp2,   vip,   gfx,   mm,    lcd,   vpp,   mmc01, mmc23,    mmc45, usbpll,
1034        usb0,  usb1,  maxclk,
1035};
1036
1037static __initdata struct clk_hw* prima2_clk_hw_array[maxclk] = {
1038        NULL, /* dummy */
1039        NULL,
1040        &clk_pll1.hw,
1041        &clk_pll2.hw,
1042        &clk_pll3.hw,
1043        &clk_mem.hw,
1044        &clk_sys.hw,
1045        &clk_security.hw,
1046        &clk_dsp.hw,
1047        &clk_gps.hw,
1048        &clk_mf.hw,
1049        &clk_io.hw,
1050        &clk_cpu.hw,
1051        &clk_uart0.hw,
1052        &clk_uart1.hw,
1053        &clk_uart2.hw,
1054        &clk_tsc.hw,
1055        &clk_i2c0.hw,
1056        &clk_i2c1.hw,
1057        &clk_spi0.hw,
1058        &clk_spi1.hw,
1059        &clk_pwmc.hw,
1060        &clk_efuse.hw,
1061        &clk_pulse.hw,
1062        &clk_dmac0.hw,
1063        &clk_dmac1.hw,
1064        &clk_nand.hw,
1065        &clk_audio.hw,
1066        &clk_usp0.hw,
1067        &clk_usp1.hw,
1068        &clk_usp2.hw,
1069        &clk_vip.hw,
1070        &clk_gfx.hw,
1071        &clk_mm.hw,
1072        &clk_lcd.hw,
1073        &clk_vpp.hw,
1074        &clk_mmc01.hw,
1075        &clk_mmc23.hw,
1076        &clk_mmc45.hw,
1077        &usb_pll_clk_hw,
1078        &clk_usb0.hw,
1079        &clk_usb1.hw,
1080};
1081
1082static struct clk *prima2_clks[maxclk];
1083static struct clk_onecell_data clk_data;
1084
1085void __init sirfsoc_of_clk_init(void)
1086{
1087        struct device_node *np;
1088        int i;
1089
1090        np = of_find_matching_node(NULL, rsc_ids);
1091        if (!np)
1092                panic("unable to find compatible rsc node in dtb\n");
1093
1094        sirfsoc_rsc_vbase = of_iomap(np, 0);
1095        if (!sirfsoc_rsc_vbase)
1096                panic("unable to map rsc registers\n");
1097
1098        of_node_put(np);
1099
1100        np = of_find_matching_node(NULL, clkc_ids);
1101        if (!np)
1102                return;
1103
1104        sirfsoc_clk_vbase = of_iomap(np, 0);
1105        if (!sirfsoc_clk_vbase)
1106                panic("unable to map clkc registers\n");
1107
1108        /* These are always available (RTC and 26MHz OSC)*/
1109        prima2_clks[rtc] = clk_register_fixed_rate(NULL, "rtc", NULL,
1110                CLK_IS_ROOT, 32768);
1111        prima2_clks[osc]= clk_register_fixed_rate(NULL, "osc", NULL,
1112                CLK_IS_ROOT, 26000000);
1113
1114        for (i = pll1; i < maxclk; i++) {
1115                prima2_clks[i] = clk_register(NULL, prima2_clk_hw_array[i]);
1116                BUG_ON(IS_ERR(prima2_clks[i]));
1117        }
1118        clk_register_clkdev(prima2_clks[cpu], NULL, "cpu");
1119        clk_register_clkdev(prima2_clks[io],  NULL, "io");
1120        clk_register_clkdev(prima2_clks[mem],  NULL, "mem");
1121
1122        clk_data.clks = prima2_clks;
1123        clk_data.clk_num = maxclk;
1124
1125        of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
1126}
1127
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.