linux/drivers/clk/clk-qoriq.c
<<
>>
Prefs
   1/*
   2 * Copyright 2013 Freescale Semiconductor, Inc.
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of the GNU General Public License version 2 as
   6 * published by the Free Software Foundation.
   7 *
   8 * clock driver for Freescale QorIQ SoCs.
   9 */
  10
  11#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  12
  13#include <linux/clk.h>
  14#include <linux/clk-provider.h>
  15#include <linux/fsl/guts.h>
  16#include <linux/io.h>
  17#include <linux/kernel.h>
  18#include <linux/module.h>
  19#include <linux/of_address.h>
  20#include <linux/of_platform.h>
  21#include <linux/of.h>
  22#include <linux/slab.h>
  23
  24#define PLL_DIV1        0
  25#define PLL_DIV2        1
  26#define PLL_DIV3        2
  27#define PLL_DIV4        3
  28
  29#define PLATFORM_PLL    0
  30#define CGA_PLL1        1
  31#define CGA_PLL2        2
  32#define CGA_PLL3        3
  33#define CGA_PLL4        4       /* only on clockgen-1.0, which lacks CGB */
  34#define CGB_PLL1        4
  35#define CGB_PLL2        5
  36
  37struct clockgen_pll_div {
  38        struct clk *clk;
  39        char name[32];
  40};
  41
  42struct clockgen_pll {
  43        struct clockgen_pll_div div[4];
  44};
  45
  46#define CLKSEL_VALID    1
  47#define CLKSEL_80PCT    2       /* Only allowed if PLL <= 80% of max cpu freq */
  48
  49struct clockgen_sourceinfo {
  50        u32 flags;      /* CLKSEL_xxx */
  51        int pll;        /* CGx_PLLn */
  52        int div;        /* PLL_DIVn */
  53};
  54
  55#define NUM_MUX_PARENTS 16
  56
  57struct clockgen_muxinfo {
  58        struct clockgen_sourceinfo clksel[NUM_MUX_PARENTS];
  59};
  60
  61#define NUM_HWACCEL     5
  62#define NUM_CMUX        8
  63
  64struct clockgen;
  65
  66/*
  67 * cmux freq must be >= platform pll.
  68 * If not set, cmux freq must be >= platform pll/2
  69 */
  70#define CG_CMUX_GE_PLAT         1
  71
  72#define CG_PLL_8BIT             2       /* PLLCnGSR[CFG] is 8 bits, not 6 */
  73#define CG_VER3                 4       /* version 3 cg: reg layout different */
  74#define CG_LITTLE_ENDIAN        8
  75
  76struct clockgen_chipinfo {
  77        const char *compat, *guts_compat;
  78        const struct clockgen_muxinfo *cmux_groups[2];
  79        const struct clockgen_muxinfo *hwaccel[NUM_HWACCEL];
  80        void (*init_periph)(struct clockgen *cg);
  81        int cmux_to_group[NUM_CMUX]; /* -1 terminates if fewer than NUM_CMUX */
  82        u32 pll_mask;   /* 1 << n bit set if PLL n is valid */
  83        u32 flags;      /* CG_xxx */
  84};
  85
  86struct clockgen {
  87        struct device_node *node;
  88        void __iomem *regs;
  89        struct clockgen_chipinfo info; /* mutable copy */
  90        struct clk *sysclk;
  91        struct clockgen_pll pll[6];
  92        struct clk *cmux[NUM_CMUX];
  93        struct clk *hwaccel[NUM_HWACCEL];
  94        struct clk *fman[2];
  95        struct ccsr_guts __iomem *guts;
  96};
  97
  98static struct clockgen clockgen;
  99
 100static void cg_out(struct clockgen *cg, u32 val, u32 __iomem *reg)
 101{
 102        if (cg->info.flags & CG_LITTLE_ENDIAN)
 103                iowrite32(val, reg);
 104        else
 105                iowrite32be(val, reg);
 106}
 107
 108static u32 cg_in(struct clockgen *cg, u32 __iomem *reg)
 109{
 110        u32 val;
 111
 112        if (cg->info.flags & CG_LITTLE_ENDIAN)
 113                val = ioread32(reg);
 114        else
 115                val = ioread32be(reg);
 116
 117        return val;
 118}
 119
 120static const struct clockgen_muxinfo p2041_cmux_grp1 = {
 121        {
 122                [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
 123                [1] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
 124                [4] = { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 },
 125        }
 126};
 127
 128static const struct clockgen_muxinfo p2041_cmux_grp2 = {
 129        {
 130                [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
 131                [4] = { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 },
 132                [5] = { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
 133        }
 134};
 135
 136static const struct clockgen_muxinfo p5020_cmux_grp1 = {
 137        {
 138                [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
 139                [1] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
 140                [4] = { CLKSEL_VALID | CLKSEL_80PCT, CGA_PLL2, PLL_DIV1 },
 141        }
 142};
 143
 144static const struct clockgen_muxinfo p5020_cmux_grp2 = {
 145        {
 146                [0] = { CLKSEL_VALID | CLKSEL_80PCT, CGA_PLL1, PLL_DIV1 },
 147                [4] = { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 },
 148                [5] = { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
 149        }
 150};
 151
 152static const struct clockgen_muxinfo p5040_cmux_grp1 = {
 153        {
 154                [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
 155                [1] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
 156                [4] = { CLKSEL_VALID | CLKSEL_80PCT, CGA_PLL2, PLL_DIV1 },
 157                [5] = { CLKSEL_VALID | CLKSEL_80PCT, CGA_PLL2, PLL_DIV2 },
 158        }
 159};
 160
 161static const struct clockgen_muxinfo p5040_cmux_grp2 = {
 162        {
 163                [0] = { CLKSEL_VALID | CLKSEL_80PCT, CGA_PLL1, PLL_DIV1 },
 164                [1] = { CLKSEL_VALID | CLKSEL_80PCT, CGA_PLL1, PLL_DIV2 },
 165                [4] = { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 },
 166                [5] = { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
 167        }
 168};
 169
 170static const struct clockgen_muxinfo p4080_cmux_grp1 = {
 171        {
 172                [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
 173                [1] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
 174                [4] = { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 },
 175                [5] = { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
 176                [8] = { CLKSEL_VALID | CLKSEL_80PCT, CGA_PLL3, PLL_DIV1 },
 177        }
 178};
 179
 180static const struct clockgen_muxinfo p4080_cmux_grp2 = {
 181        {
 182                [0] = { CLKSEL_VALID | CLKSEL_80PCT, CGA_PLL1, PLL_DIV1 },
 183                [8] = { CLKSEL_VALID, CGA_PLL3, PLL_DIV1 },
 184                [9] = { CLKSEL_VALID, CGA_PLL3, PLL_DIV2 },
 185                [12] = { CLKSEL_VALID, CGA_PLL4, PLL_DIV1 },
 186                [13] = { CLKSEL_VALID, CGA_PLL4, PLL_DIV2 },
 187        }
 188};
 189
 190static const struct clockgen_muxinfo t1023_cmux = {
 191        {
 192                [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
 193                [1] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
 194        }
 195};
 196
 197static const struct clockgen_muxinfo t1040_cmux = {
 198        {
 199                [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
 200                [1] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
 201                [4] = { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 },
 202                [5] = { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
 203        }
 204};
 205
 206
 207static const struct clockgen_muxinfo clockgen2_cmux_cga = {
 208        {
 209                { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
 210                { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
 211                { CLKSEL_VALID, CGA_PLL1, PLL_DIV4 },
 212                {},
 213                { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 },
 214                { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
 215                { CLKSEL_VALID, CGA_PLL2, PLL_DIV4 },
 216                {},
 217                { CLKSEL_VALID, CGA_PLL3, PLL_DIV1 },
 218                { CLKSEL_VALID, CGA_PLL3, PLL_DIV2 },
 219                { CLKSEL_VALID, CGA_PLL3, PLL_DIV4 },
 220        },
 221};
 222
 223static const struct clockgen_muxinfo clockgen2_cmux_cga12 = {
 224        {
 225                { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
 226                { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
 227                { CLKSEL_VALID, CGA_PLL1, PLL_DIV4 },
 228                {},
 229                { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 },
 230                { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
 231                { CLKSEL_VALID, CGA_PLL2, PLL_DIV4 },
 232        },
 233};
 234
 235static const struct clockgen_muxinfo clockgen2_cmux_cgb = {
 236        {
 237                { CLKSEL_VALID, CGB_PLL1, PLL_DIV1 },
 238                { CLKSEL_VALID, CGB_PLL1, PLL_DIV2 },
 239                { CLKSEL_VALID, CGB_PLL1, PLL_DIV4 },
 240                {},
 241                { CLKSEL_VALID, CGB_PLL2, PLL_DIV1 },
 242                { CLKSEL_VALID, CGB_PLL2, PLL_DIV2 },
 243                { CLKSEL_VALID, CGB_PLL2, PLL_DIV4 },
 244        },
 245};
 246
 247static const struct clockgen_muxinfo ls1043a_hwa1 = {
 248        {
 249                {},
 250                {},
 251                { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
 252                { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 },
 253                {},
 254                {},
 255                { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
 256                { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 },
 257        },
 258};
 259
 260static const struct clockgen_muxinfo ls1043a_hwa2 = {
 261        {
 262                {},
 263                { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 },
 264                {},
 265                { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 },
 266        },
 267};
 268
 269static const struct clockgen_muxinfo t1023_hwa1 = {
 270        {
 271                {},
 272                { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
 273                { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
 274                { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 },
 275        },
 276};
 277
 278static const struct clockgen_muxinfo t1023_hwa2 = {
 279        {
 280                [6] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
 281        },
 282};
 283
 284static const struct clockgen_muxinfo t2080_hwa1 = {
 285        {
 286                {},
 287                { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
 288                { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
 289                { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 },
 290                { CLKSEL_VALID, CGA_PLL1, PLL_DIV4 },
 291                { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 },
 292                { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
 293                { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 },
 294        },
 295};
 296
 297static const struct clockgen_muxinfo t2080_hwa2 = {
 298        {
 299                {},
 300                { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 },
 301                { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
 302                { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 },
 303                { CLKSEL_VALID, CGA_PLL2, PLL_DIV4 },
 304                { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 },
 305                { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
 306                { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 },
 307        },
 308};
 309
 310static const struct clockgen_muxinfo t4240_hwa1 = {
 311        {
 312                { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV2 },
 313                { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
 314                { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
 315                { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 },
 316                { CLKSEL_VALID, CGA_PLL1, PLL_DIV4 },
 317                {},
 318                { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
 319                { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 },
 320        },
 321};
 322
 323static const struct clockgen_muxinfo t4240_hwa4 = {
 324        {
 325                [2] = { CLKSEL_VALID, CGB_PLL1, PLL_DIV2 },
 326                [3] = { CLKSEL_VALID, CGB_PLL1, PLL_DIV3 },
 327                [4] = { CLKSEL_VALID, CGB_PLL1, PLL_DIV4 },
 328                [5] = { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 },
 329                [6] = { CLKSEL_VALID, CGB_PLL2, PLL_DIV2 },
 330        },
 331};
 332
 333static const struct clockgen_muxinfo t4240_hwa5 = {
 334        {
 335                [2] = { CLKSEL_VALID, CGB_PLL2, PLL_DIV2 },
 336                [3] = { CLKSEL_VALID, CGB_PLL2, PLL_DIV3 },
 337                [4] = { CLKSEL_VALID, CGB_PLL2, PLL_DIV4 },
 338                [5] = { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 },
 339                [6] = { CLKSEL_VALID, CGB_PLL1, PLL_DIV2 },
 340                [7] = { CLKSEL_VALID, CGB_PLL1, PLL_DIV3 },
 341        },
 342};
 343
 344#define RCWSR7_FM1_CLK_SEL      0x40000000
 345#define RCWSR7_FM2_CLK_SEL      0x20000000
 346#define RCWSR7_HWA_ASYNC_DIV    0x04000000
 347
 348static void __init p2041_init_periph(struct clockgen *cg)
 349{
 350        u32 reg;
 351
 352        reg = ioread32be(&cg->guts->rcwsr[7]);
 353
 354        if (reg & RCWSR7_FM1_CLK_SEL)
 355                cg->fman[0] = cg->pll[CGA_PLL2].div[PLL_DIV2].clk;
 356        else
 357                cg->fman[0] = cg->pll[PLATFORM_PLL].div[PLL_DIV2].clk;
 358}
 359
 360static void __init p4080_init_periph(struct clockgen *cg)
 361{
 362        u32 reg;
 363
 364        reg = ioread32be(&cg->guts->rcwsr[7]);
 365
 366        if (reg & RCWSR7_FM1_CLK_SEL)
 367                cg->fman[0] = cg->pll[CGA_PLL3].div[PLL_DIV2].clk;
 368        else
 369                cg->fman[0] = cg->pll[PLATFORM_PLL].div[PLL_DIV2].clk;
 370
 371        if (reg & RCWSR7_FM2_CLK_SEL)
 372                cg->fman[1] = cg->pll[CGA_PLL3].div[PLL_DIV2].clk;
 373        else
 374                cg->fman[1] = cg->pll[PLATFORM_PLL].div[PLL_DIV2].clk;
 375}
 376
 377static void __init p5020_init_periph(struct clockgen *cg)
 378{
 379        u32 reg;
 380        int div = PLL_DIV2;
 381
 382        reg = ioread32be(&cg->guts->rcwsr[7]);
 383        if (reg & RCWSR7_HWA_ASYNC_DIV)
 384                div = PLL_DIV4;
 385
 386        if (reg & RCWSR7_FM1_CLK_SEL)
 387                cg->fman[0] = cg->pll[CGA_PLL2].div[div].clk;
 388        else
 389                cg->fman[0] = cg->pll[PLATFORM_PLL].div[PLL_DIV2].clk;
 390}
 391
 392static void __init p5040_init_periph(struct clockgen *cg)
 393{
 394        u32 reg;
 395        int div = PLL_DIV2;
 396
 397        reg = ioread32be(&cg->guts->rcwsr[7]);
 398        if (reg & RCWSR7_HWA_ASYNC_DIV)
 399                div = PLL_DIV4;
 400
 401        if (reg & RCWSR7_FM1_CLK_SEL)
 402                cg->fman[0] = cg->pll[CGA_PLL3].div[div].clk;
 403        else
 404                cg->fman[0] = cg->pll[PLATFORM_PLL].div[PLL_DIV2].clk;
 405
 406        if (reg & RCWSR7_FM2_CLK_SEL)
 407                cg->fman[1] = cg->pll[CGA_PLL3].div[div].clk;
 408        else
 409                cg->fman[1] = cg->pll[PLATFORM_PLL].div[PLL_DIV2].clk;
 410}
 411
 412static void __init t1023_init_periph(struct clockgen *cg)
 413{
 414        cg->fman[0] = cg->hwaccel[1];
 415}
 416
 417static void __init t1040_init_periph(struct clockgen *cg)
 418{
 419        cg->fman[0] = cg->pll[PLATFORM_PLL].div[PLL_DIV1].clk;
 420}
 421
 422static void __init t2080_init_periph(struct clockgen *cg)
 423{
 424        cg->fman[0] = cg->hwaccel[0];
 425}
 426
 427static void __init t4240_init_periph(struct clockgen *cg)
 428{
 429        cg->fman[0] = cg->hwaccel[3];
 430        cg->fman[1] = cg->hwaccel[4];
 431}
 432
 433static const struct clockgen_chipinfo chipinfo[] = {
 434        {
 435                .compat = "fsl,b4420-clockgen",
 436                .guts_compat = "fsl,b4860-device-config",
 437                .init_periph = t2080_init_periph,
 438                .cmux_groups = {
 439                        &clockgen2_cmux_cga12, &clockgen2_cmux_cgb
 440                },
 441                .hwaccel = {
 442                        &t2080_hwa1
 443                },
 444                .cmux_to_group = {
 445                        0, 1, 1, 1, -1
 446                },
 447                .pll_mask = 0x3f,
 448                .flags = CG_PLL_8BIT,
 449        },
 450        {
 451                .compat = "fsl,b4860-clockgen",
 452                .guts_compat = "fsl,b4860-device-config",
 453                .init_periph = t2080_init_periph,
 454                .cmux_groups = {
 455                        &clockgen2_cmux_cga12, &clockgen2_cmux_cgb
 456                },
 457                .hwaccel = {
 458                        &t2080_hwa1
 459                },
 460                .cmux_to_group = {
 461                        0, 1, 1, 1, -1
 462                },
 463                .pll_mask = 0x3f,
 464                .flags = CG_PLL_8BIT,
 465        },
 466        {
 467                .compat = "fsl,ls1021a-clockgen",
 468                .cmux_groups = {
 469                        &t1023_cmux
 470                },
 471                .cmux_to_group = {
 472                        0, -1
 473                },
 474                .pll_mask = 0x03,
 475        },
 476        {
 477                .compat = "fsl,ls1043a-clockgen",
 478                .init_periph = t2080_init_periph,
 479                .cmux_groups = {
 480                        &t1040_cmux
 481                },
 482                .hwaccel = {
 483                        &ls1043a_hwa1, &ls1043a_hwa2
 484                },
 485                .cmux_to_group = {
 486                        0, -1
 487                },
 488                .pll_mask = 0x07,
 489                .flags = CG_PLL_8BIT,
 490        },
 491        {
 492                .compat = "fsl,ls2080a-clockgen",
 493                .cmux_groups = {
 494                        &clockgen2_cmux_cga12, &clockgen2_cmux_cgb
 495                },
 496                .cmux_to_group = {
 497                        0, 0, 1, 1, -1
 498                },
 499                .pll_mask = 0x37,
 500                .flags = CG_VER3 | CG_LITTLE_ENDIAN,
 501        },
 502        {
 503                .compat = "fsl,p2041-clockgen",
 504                .guts_compat = "fsl,qoriq-device-config-1.0",
 505                .init_periph = p2041_init_periph,
 506                .cmux_groups = {
 507                        &p2041_cmux_grp1, &p2041_cmux_grp2
 508                },
 509                .cmux_to_group = {
 510                        0, 0, 1, 1, -1
 511                },
 512                .pll_mask = 0x07,
 513        },
 514        {
 515                .compat = "fsl,p3041-clockgen",
 516                .guts_compat = "fsl,qoriq-device-config-1.0",
 517                .init_periph = p2041_init_periph,
 518                .cmux_groups = {
 519                        &p2041_cmux_grp1, &p2041_cmux_grp2
 520                },
 521                .cmux_to_group = {
 522                        0, 0, 1, 1, -1
 523                },
 524                .pll_mask = 0x07,
 525        },
 526        {
 527                .compat = "fsl,p4080-clockgen",
 528                .guts_compat = "fsl,qoriq-device-config-1.0",
 529                .init_periph = p4080_init_periph,
 530                .cmux_groups = {
 531                        &p4080_cmux_grp1, &p4080_cmux_grp2
 532                },
 533                .cmux_to_group = {
 534                        0, 0, 0, 0, 1, 1, 1, 1
 535                },
 536                .pll_mask = 0x1f,
 537        },
 538        {
 539                .compat = "fsl,p5020-clockgen",
 540                .guts_compat = "fsl,qoriq-device-config-1.0",
 541                .init_periph = p5020_init_periph,
 542                .cmux_groups = {
 543                        &p2041_cmux_grp1, &p2041_cmux_grp2
 544                },
 545                .cmux_to_group = {
 546                        0, 1, -1
 547                },
 548                .pll_mask = 0x07,
 549        },
 550        {
 551                .compat = "fsl,p5040-clockgen",
 552                .guts_compat = "fsl,p5040-device-config",
 553                .init_periph = p5040_init_periph,
 554                .cmux_groups = {
 555                        &p5040_cmux_grp1, &p5040_cmux_grp2
 556                },
 557                .cmux_to_group = {
 558                        0, 0, 1, 1, -1
 559                },
 560                .pll_mask = 0x0f,
 561        },
 562        {
 563                .compat = "fsl,t1023-clockgen",
 564                .guts_compat = "fsl,t1023-device-config",
 565                .init_periph = t1023_init_periph,
 566                .cmux_groups = {
 567                        &t1023_cmux
 568                },
 569                .hwaccel = {
 570                        &t1023_hwa1, &t1023_hwa2
 571                },
 572                .cmux_to_group = {
 573                        0, 0, -1
 574                },
 575                .pll_mask = 0x03,
 576                .flags = CG_PLL_8BIT,
 577        },
 578        {
 579                .compat = "fsl,t1040-clockgen",
 580                .guts_compat = "fsl,t1040-device-config",
 581                .init_periph = t1040_init_periph,
 582                .cmux_groups = {
 583                        &t1040_cmux
 584                },
 585                .cmux_to_group = {
 586                        0, 0, 0, 0, -1
 587                },
 588                .pll_mask = 0x07,
 589                .flags = CG_PLL_8BIT,
 590        },
 591        {
 592                .compat = "fsl,t2080-clockgen",
 593                .guts_compat = "fsl,t2080-device-config",
 594                .init_periph = t2080_init_periph,
 595                .cmux_groups = {
 596                        &clockgen2_cmux_cga12
 597                },
 598                .hwaccel = {
 599                        &t2080_hwa1, &t2080_hwa2
 600                },
 601                .cmux_to_group = {
 602                        0, -1
 603                },
 604                .pll_mask = 0x07,
 605                .flags = CG_PLL_8BIT,
 606        },
 607        {
 608                .compat = "fsl,t4240-clockgen",
 609                .guts_compat = "fsl,t4240-device-config",
 610                .init_periph = t4240_init_periph,
 611                .cmux_groups = {
 612                        &clockgen2_cmux_cga, &clockgen2_cmux_cgb
 613                },
 614                .hwaccel = {
 615                        &t4240_hwa1, NULL, NULL, &t4240_hwa4, &t4240_hwa5
 616                },
 617                .cmux_to_group = {
 618                        0, 0, 1, -1
 619                },
 620                .pll_mask = 0x3f,
 621                .flags = CG_PLL_8BIT,
 622        },
 623        {},
 624};
 625
 626struct mux_hwclock {
 627        struct clk_hw hw;
 628        struct clockgen *cg;
 629        const struct clockgen_muxinfo *info;
 630        u32 __iomem *reg;
 631        u8 parent_to_clksel[NUM_MUX_PARENTS];
 632        s8 clksel_to_parent[NUM_MUX_PARENTS];
 633        int num_parents;
 634};
 635
 636#define to_mux_hwclock(p)       container_of(p, struct mux_hwclock, hw)
 637#define CLKSEL_MASK             0x78000000
 638#define CLKSEL_SHIFT            27
 639
 640static int mux_set_parent(struct clk_hw *hw, u8 idx)
 641{
 642        struct mux_hwclock *hwc = to_mux_hwclock(hw);
 643        u32 clksel;
 644
 645        if (idx >= hwc->num_parents)
 646                return -EINVAL;
 647
 648        clksel = hwc->parent_to_clksel[idx];
 649        cg_out(hwc->cg, (clksel << CLKSEL_SHIFT) & CLKSEL_MASK, hwc->reg);
 650
 651        return 0;
 652}
 653
 654static u8 mux_get_parent(struct clk_hw *hw)
 655{
 656        struct mux_hwclock *hwc = to_mux_hwclock(hw);
 657        u32 clksel;
 658        s8 ret;
 659
 660        clksel = (cg_in(hwc->cg, hwc->reg) & CLKSEL_MASK) >> CLKSEL_SHIFT;
 661
 662        ret = hwc->clksel_to_parent[clksel];
 663        if (ret < 0) {
 664                pr_err("%s: mux at %p has bad clksel\n", __func__, hwc->reg);
 665                return 0;
 666        }
 667
 668        return ret;
 669}
 670
 671static const struct clk_ops cmux_ops = {
 672        .get_parent = mux_get_parent,
 673        .set_parent = mux_set_parent,
 674};
 675
 676/*
 677 * Don't allow setting for now, as the clock options haven't been
 678 * sanitized for additional restrictions.
 679 */
 680static const struct clk_ops hwaccel_ops = {
 681        .get_parent = mux_get_parent,
 682};
 683
 684static const struct clockgen_pll_div *get_pll_div(struct clockgen *cg,
 685                                                  struct mux_hwclock *hwc,
 686                                                  int idx)
 687{
 688        int pll, div;
 689
 690        if (!(hwc->info->clksel[idx].flags & CLKSEL_VALID))
 691                return NULL;
 692
 693        pll = hwc->info->clksel[idx].pll;
 694        div = hwc->info->clksel[idx].div;
 695
 696        return &cg->pll[pll].div[div];
 697}
 698
 699static struct clk * __init create_mux_common(struct clockgen *cg,
 700                                             struct mux_hwclock *hwc,
 701                                             const struct clk_ops *ops,
 702                                             unsigned long min_rate,
 703                                             unsigned long max_rate,
 704                                             unsigned long pct80_rate,
 705                                             const char *fmt, int idx)
 706{
 707        struct clk_init_data init = {};
 708        struct clk *clk;
 709        const struct clockgen_pll_div *div;
 710        const char *parent_names[NUM_MUX_PARENTS];
 711        char name[32];
 712        int i, j;
 713
 714        snprintf(name, sizeof(name), fmt, idx);
 715
 716        for (i = 0, j = 0; i < NUM_MUX_PARENTS; i++) {
 717                unsigned long rate;
 718
 719                hwc->clksel_to_parent[i] = -1;
 720
 721                div = get_pll_div(cg, hwc, i);
 722                if (!div)
 723                        continue;
 724
 725                rate = clk_get_rate(div->clk);
 726
 727                if (hwc->info->clksel[i].flags & CLKSEL_80PCT &&
 728                    rate > pct80_rate)
 729                        continue;
 730                if (rate < min_rate)
 731                        continue;
 732                if (rate > max_rate)
 733                        continue;
 734
 735                parent_names[j] = div->name;
 736                hwc->parent_to_clksel[j] = i;
 737                hwc->clksel_to_parent[i] = j;
 738                j++;
 739        }
 740
 741        init.name = name;
 742        init.ops = ops;
 743        init.parent_names = parent_names;
 744        init.num_parents = hwc->num_parents = j;
 745        init.flags = 0;
 746        hwc->hw.init = &init;
 747        hwc->cg = cg;
 748
 749        clk = clk_register(NULL, &hwc->hw);
 750        if (IS_ERR(clk)) {
 751                pr_err("%s: Couldn't register %s: %ld\n", __func__, name,
 752                       PTR_ERR(clk));
 753                kfree(hwc);
 754                return NULL;
 755        }
 756
 757        return clk;
 758}
 759
 760static struct clk * __init create_one_cmux(struct clockgen *cg, int idx)
 761{
 762        struct mux_hwclock *hwc;
 763        const struct clockgen_pll_div *div;
 764        unsigned long plat_rate, min_rate;
 765        u64 max_rate, pct80_rate;
 766        u32 clksel;
 767
 768        hwc = kzalloc(sizeof(*hwc), GFP_KERNEL);
 769        if (!hwc)
 770                return NULL;
 771
 772        if (cg->info.flags & CG_VER3)
 773                hwc->reg = cg->regs + 0x70000 + 0x20 * idx;
 774        else
 775                hwc->reg = cg->regs + 0x20 * idx;
 776
 777        hwc->info = cg->info.cmux_groups[cg->info.cmux_to_group[idx]];
 778
 779        /*
 780         * Find the rate for the default clksel, and treat it as the
 781         * maximum rated core frequency.  If this is an incorrect
 782         * assumption, certain clock options (possibly including the
 783         * default clksel) may be inappropriately excluded on certain
 784         * chips.
 785         */
 786        clksel = (cg_in(cg, hwc->reg) & CLKSEL_MASK) >> CLKSEL_SHIFT;
 787        div = get_pll_div(cg, hwc, clksel);
 788        if (!div) {
 789                kfree(hwc);
 790                return NULL;
 791        }
 792
 793        max_rate = clk_get_rate(div->clk);
 794        pct80_rate = max_rate * 8;
 795        do_div(pct80_rate, 10);
 796
 797        plat_rate = clk_get_rate(cg->pll[PLATFORM_PLL].div[PLL_DIV1].clk);
 798
 799        if (cg->info.flags & CG_CMUX_GE_PLAT)
 800                min_rate = plat_rate;
 801        else
 802                min_rate = plat_rate / 2;
 803
 804        return create_mux_common(cg, hwc, &cmux_ops, min_rate, max_rate,
 805                                 pct80_rate, "cg-cmux%d", idx);
 806}
 807
 808static struct clk * __init create_one_hwaccel(struct clockgen *cg, int idx)
 809{
 810        struct mux_hwclock *hwc;
 811
 812        hwc = kzalloc(sizeof(*hwc), GFP_KERNEL);
 813        if (!hwc)
 814                return NULL;
 815
 816        hwc->reg = cg->regs + 0x20 * idx + 0x10;
 817        hwc->info = cg->info.hwaccel[idx];
 818
 819        return create_mux_common(cg, hwc, &hwaccel_ops, 0, ULONG_MAX, 0,
 820                                 "cg-hwaccel%d", idx);
 821}
 822
 823static void __init create_muxes(struct clockgen *cg)
 824{
 825        int i;
 826
 827        for (i = 0; i < ARRAY_SIZE(cg->cmux); i++) {
 828                if (cg->info.cmux_to_group[i] < 0)
 829                        break;
 830                if (cg->info.cmux_to_group[i] >=
 831                    ARRAY_SIZE(cg->info.cmux_groups)) {
 832                        WARN_ON_ONCE(1);
 833                        continue;
 834                }
 835
 836                cg->cmux[i] = create_one_cmux(cg, i);
 837        }
 838
 839        for (i = 0; i < ARRAY_SIZE(cg->hwaccel); i++) {
 840                if (!cg->info.hwaccel[i])
 841                        continue;
 842
 843                cg->hwaccel[i] = create_one_hwaccel(cg, i);
 844        }
 845}
 846
 847static void __init clockgen_init(struct device_node *np);
 848
 849/* Legacy nodes may get probed before the parent clockgen node */
 850static void __init legacy_init_clockgen(struct device_node *np)
 851{
 852        if (!clockgen.node)
 853                clockgen_init(of_get_parent(np));
 854}
 855
 856/* Legacy node */
 857static void __init core_mux_init(struct device_node *np)
 858{
 859        struct clk *clk;
 860        struct resource res;
 861        int idx, rc;
 862
 863        legacy_init_clockgen(np);
 864
 865        if (of_address_to_resource(np, 0, &res))
 866                return;
 867
 868        idx = (res.start & 0xf0) >> 5;
 869        clk = clockgen.cmux[idx];
 870
 871        rc = of_clk_add_provider(np, of_clk_src_simple_get, clk);
 872        if (rc) {
 873                pr_err("%s: Couldn't register clk provider for node %s: %d\n",
 874                       __func__, np->name, rc);
 875                return;
 876        }
 877}
 878
 879static struct clk __init
 880*sysclk_from_fixed(struct device_node *node, const char *name)
 881{
 882        u32 rate;
 883
 884        if (of_property_read_u32(node, "clock-frequency", &rate))
 885                return ERR_PTR(-ENODEV);
 886
 887        return clk_register_fixed_rate(NULL, name, NULL, 0, rate);
 888}
 889
 890static struct clk *sysclk_from_parent(const char *name)
 891{
 892        struct clk *clk;
 893        const char *parent_name;
 894
 895        clk = of_clk_get(clockgen.node, 0);
 896        if (IS_ERR(clk))
 897                return clk;
 898
 899        /* Register the input clock under the desired name. */
 900        parent_name = __clk_get_name(clk);
 901        clk = clk_register_fixed_factor(NULL, name, parent_name,
 902                                        0, 1, 1);
 903        if (IS_ERR(clk))
 904                pr_err("%s: Couldn't register %s: %ld\n", __func__, name,
 905                       PTR_ERR(clk));
 906
 907        return clk;
 908}
 909
 910static struct clk * __init create_sysclk(const char *name)
 911{
 912        struct device_node *sysclk;
 913        struct clk *clk;
 914
 915        clk = sysclk_from_fixed(clockgen.node, name);
 916        if (!IS_ERR(clk))
 917                return clk;
 918
 919        clk = sysclk_from_parent(name);
 920        if (!IS_ERR(clk))
 921                return clk;
 922
 923        sysclk = of_get_child_by_name(clockgen.node, "sysclk");
 924        if (sysclk) {
 925                clk = sysclk_from_fixed(sysclk, name);
 926                if (!IS_ERR(clk))
 927                        return clk;
 928        }
 929
 930        pr_err("%s: No input clock\n", __func__);
 931        return NULL;
 932}
 933
 934/* Legacy node */
 935static void __init sysclk_init(struct device_node *node)
 936{
 937        struct clk *clk;
 938
 939        legacy_init_clockgen(node);
 940
 941        clk = clockgen.sysclk;
 942        if (clk)
 943                of_clk_add_provider(node, of_clk_src_simple_get, clk);
 944}
 945
 946#define PLL_KILL BIT(31)
 947
 948static void __init create_one_pll(struct clockgen *cg, int idx)
 949{
 950        u32 __iomem *reg;
 951        u32 mult;
 952        struct clockgen_pll *pll = &cg->pll[idx];
 953        int i;
 954
 955        if (!(cg->info.pll_mask & (1 << idx)))
 956                return;
 957
 958        if (cg->info.flags & CG_VER3) {
 959                switch (idx) {
 960                case PLATFORM_PLL:
 961                        reg = cg->regs + 0x60080;
 962                        break;
 963                case CGA_PLL1:
 964                        reg = cg->regs + 0x80;
 965                        break;
 966                case CGA_PLL2:
 967                        reg = cg->regs + 0xa0;
 968                        break;
 969                case CGB_PLL1:
 970                        reg = cg->regs + 0x10080;
 971                        break;
 972                case CGB_PLL2:
 973                        reg = cg->regs + 0x100a0;
 974                        break;
 975                default:
 976                        WARN_ONCE(1, "index %d\n", idx);
 977                        return;
 978                }
 979        } else {
 980                if (idx == PLATFORM_PLL)
 981                        reg = cg->regs + 0xc00;
 982                else
 983                        reg = cg->regs + 0x800 + 0x20 * (idx - 1);
 984        }
 985
 986        /* Get the multiple of PLL */
 987        mult = cg_in(cg, reg);
 988
 989        /* Check if this PLL is disabled */
 990        if (mult & PLL_KILL) {
 991                pr_debug("%s(): pll %p disabled\n", __func__, reg);
 992                return;
 993        }
 994
 995        if ((cg->info.flags & CG_VER3) ||
 996            ((cg->info.flags & CG_PLL_8BIT) && idx != PLATFORM_PLL))
 997                mult = (mult & GENMASK(8, 1)) >> 1;
 998        else
 999                mult = (mult & GENMASK(6, 1)) >> 1;
1000
1001        for (i = 0; i < ARRAY_SIZE(pll->div); i++) {
1002                struct clk *clk;
1003
1004                snprintf(pll->div[i].name, sizeof(pll->div[i].name),
1005                         "cg-pll%d-div%d", idx, i + 1);
1006
1007                clk = clk_register_fixed_factor(NULL,
1008                                pll->div[i].name, "cg-sysclk", 0, mult, i + 1);
1009                if (IS_ERR(clk)) {
1010                        pr_err("%s: %s: register failed %ld\n",
1011                               __func__, pll->div[i].name, PTR_ERR(clk));
1012                        continue;
1013                }
1014
1015                pll->div[i].clk = clk;
1016        }
1017}
1018
1019static void __init create_plls(struct clockgen *cg)
1020{
1021        int i;
1022
1023        for (i = 0; i < ARRAY_SIZE(cg->pll); i++)
1024                create_one_pll(cg, i);
1025}
1026
1027static void __init legacy_pll_init(struct device_node *np, int idx)
1028{
1029        struct clockgen_pll *pll;
1030        struct clk_onecell_data *onecell_data;
1031        struct clk **subclks;
1032        int count, rc;
1033
1034        legacy_init_clockgen(np);
1035
1036        pll = &clockgen.pll[idx];
1037        count = of_property_count_strings(np, "clock-output-names");
1038
1039        BUILD_BUG_ON(ARRAY_SIZE(pll->div) < 4);
1040        subclks = kcalloc(4, sizeof(struct clk *), GFP_KERNEL);
1041        if (!subclks)
1042                return;
1043
1044        onecell_data = kmalloc(sizeof(*onecell_data), GFP_KERNEL);
1045        if (!onecell_data)
1046                goto err_clks;
1047
1048        if (count <= 3) {
1049                subclks[0] = pll->div[0].clk;
1050                subclks[1] = pll->div[1].clk;
1051                subclks[2] = pll->div[3].clk;
1052        } else {
1053                subclks[0] = pll->div[0].clk;
1054                subclks[1] = pll->div[1].clk;
1055                subclks[2] = pll->div[2].clk;
1056                subclks[3] = pll->div[3].clk;
1057        }
1058
1059        onecell_data->clks = subclks;
1060        onecell_data->clk_num = count;
1061
1062        rc = of_clk_add_provider(np, of_clk_src_onecell_get, onecell_data);
1063        if (rc) {
1064                pr_err("%s: Couldn't register clk provider for node %s: %d\n",
1065                       __func__, np->name, rc);
1066                goto err_cell;
1067        }
1068
1069        return;
1070err_cell:
1071        kfree(onecell_data);
1072err_clks:
1073        kfree(subclks);
1074}
1075
1076/* Legacy node */
1077static void __init pltfrm_pll_init(struct device_node *np)
1078{
1079        legacy_pll_init(np, PLATFORM_PLL);
1080}
1081
1082/* Legacy node */
1083static void __init core_pll_init(struct device_node *np)
1084{
1085        struct resource res;
1086        int idx;
1087
1088        if (of_address_to_resource(np, 0, &res))
1089                return;
1090
1091        if ((res.start & 0xfff) == 0xc00) {
1092                /*
1093                 * ls1021a devtree labels the platform PLL
1094                 * with the core PLL compatible
1095                 */
1096                pltfrm_pll_init(np);
1097        } else {
1098                idx = (res.start & 0xf0) >> 5;
1099                legacy_pll_init(np, CGA_PLL1 + idx);
1100        }
1101}
1102
1103static struct clk *clockgen_clk_get(struct of_phandle_args *clkspec, void *data)
1104{
1105        struct clockgen *cg = data;
1106        struct clk *clk;
1107        struct clockgen_pll *pll;
1108        u32 type, idx;
1109
1110        if (clkspec->args_count < 2) {
1111                pr_err("%s: insufficient phandle args\n", __func__);
1112                return ERR_PTR(-EINVAL);
1113        }
1114
1115        type = clkspec->args[0];
1116        idx = clkspec->args[1];
1117
1118        switch (type) {
1119        case 0:
1120                if (idx != 0)
1121                        goto bad_args;
1122                clk = cg->sysclk;
1123                break;
1124        case 1:
1125                if (idx >= ARRAY_SIZE(cg->cmux))
1126                        goto bad_args;
1127                clk = cg->cmux[idx];
1128                break;
1129        case 2:
1130                if (idx >= ARRAY_SIZE(cg->hwaccel))
1131                        goto bad_args;
1132                clk = cg->hwaccel[idx];
1133                break;
1134        case 3:
1135                if (idx >= ARRAY_SIZE(cg->fman))
1136                        goto bad_args;
1137                clk = cg->fman[idx];
1138                break;
1139        case 4:
1140                pll = &cg->pll[PLATFORM_PLL];
1141                if (idx >= ARRAY_SIZE(pll->div))
1142                        goto bad_args;
1143                clk = pll->div[idx].clk;
1144                break;
1145        default:
1146                goto bad_args;
1147        }
1148
1149        if (!clk)
1150                return ERR_PTR(-ENOENT);
1151        return clk;
1152
1153bad_args:
1154        pr_err("%s: Bad phandle args %u %u\n", __func__, type, idx);
1155        return ERR_PTR(-EINVAL);
1156}
1157
1158#ifdef CONFIG_PPC
1159#include <asm/mpc85xx.h>
1160
1161static const u32 a4510_svrs[] __initconst = {
1162        (SVR_P2040 << 8) | 0x10,        /* P2040 1.0 */
1163        (SVR_P2040 << 8) | 0x11,        /* P2040 1.1 */
1164        (SVR_P2041 << 8) | 0x10,        /* P2041 1.0 */
1165        (SVR_P2041 << 8) | 0x11,        /* P2041 1.1 */
1166        (SVR_P3041 << 8) | 0x10,        /* P3041 1.0 */
1167        (SVR_P3041 << 8) | 0x11,        /* P3041 1.1 */
1168        (SVR_P4040 << 8) | 0x20,        /* P4040 2.0 */
1169        (SVR_P4080 << 8) | 0x20,        /* P4080 2.0 */
1170        (SVR_P5010 << 8) | 0x10,        /* P5010 1.0 */
1171        (SVR_P5010 << 8) | 0x20,        /* P5010 2.0 */
1172        (SVR_P5020 << 8) | 0x10,        /* P5020 1.0 */
1173        (SVR_P5021 << 8) | 0x10,        /* P5021 1.0 */
1174        (SVR_P5040 << 8) | 0x10,        /* P5040 1.0 */
1175};
1176
1177#define SVR_SECURITY    0x80000 /* The Security (E) bit */
1178
1179static bool __init has_erratum_a4510(void)
1180{
1181        u32 svr = mfspr(SPRN_SVR);
1182        int i;
1183
1184        svr &= ~SVR_SECURITY;
1185
1186        for (i = 0; i < ARRAY_SIZE(a4510_svrs); i++) {
1187                if (svr == a4510_svrs[i])
1188                        return true;
1189        }
1190
1191        return false;
1192}
1193#else
1194static bool __init has_erratum_a4510(void)
1195{
1196        return false;
1197}
1198#endif
1199
1200static void __init clockgen_init(struct device_node *np)
1201{
1202        int i, ret;
1203        bool is_old_ls1021a = false;
1204
1205        /* May have already been called by a legacy probe */
1206        if (clockgen.node)
1207                return;
1208
1209        clockgen.node = np;
1210        clockgen.regs = of_iomap(np, 0);
1211        if (!clockgen.regs &&
1212            of_device_is_compatible(of_root, "fsl,ls1021a")) {
1213                /* Compatibility hack for old, broken device trees */
1214                clockgen.regs = ioremap(0x1ee1000, 0x1000);
1215                is_old_ls1021a = true;
1216        }
1217        if (!clockgen.regs) {
1218                pr_err("%s(): %s: of_iomap() failed\n", __func__, np->name);
1219                return;
1220        }
1221
1222        for (i = 0; i < ARRAY_SIZE(chipinfo); i++) {
1223                if (of_device_is_compatible(np, chipinfo[i].compat))
1224                        break;
1225                if (is_old_ls1021a &&
1226                    !strcmp(chipinfo[i].compat, "fsl,ls1021a-clockgen"))
1227                        break;
1228        }
1229
1230        if (i == ARRAY_SIZE(chipinfo)) {
1231                pr_err("%s: unknown clockgen node %s\n", __func__,
1232                       np->full_name);
1233                goto err;
1234        }
1235        clockgen.info = chipinfo[i];
1236
1237        if (clockgen.info.guts_compat) {
1238                struct device_node *guts;
1239
1240                guts = of_find_compatible_node(NULL, NULL,
1241                                               clockgen.info.guts_compat);
1242                if (guts) {
1243                        clockgen.guts = of_iomap(guts, 0);
1244                        if (!clockgen.guts) {
1245                                pr_err("%s: Couldn't map %s regs\n", __func__,
1246                                       guts->full_name);
1247                        }
1248                }
1249
1250        }
1251
1252        if (has_erratum_a4510())
1253                clockgen.info.flags |= CG_CMUX_GE_PLAT;
1254
1255        clockgen.sysclk = create_sysclk("cg-sysclk");
1256        create_plls(&clockgen);
1257        create_muxes(&clockgen);
1258
1259        if (clockgen.info.init_periph)
1260                clockgen.info.init_periph(&clockgen);
1261
1262        ret = of_clk_add_provider(np, clockgen_clk_get, &clockgen);
1263        if (ret) {
1264                pr_err("%s: Couldn't register clk provider for node %s: %d\n",
1265                       __func__, np->name, ret);
1266        }
1267
1268        return;
1269err:
1270        iounmap(clockgen.regs);
1271        clockgen.regs = NULL;
1272}
1273
1274CLK_OF_DECLARE(qoriq_clockgen_1, "fsl,qoriq-clockgen-1.0", clockgen_init);
1275CLK_OF_DECLARE(qoriq_clockgen_2, "fsl,qoriq-clockgen-2.0", clockgen_init);
1276CLK_OF_DECLARE(qoriq_clockgen_ls1021a, "fsl,ls1021a-clockgen", clockgen_init);
1277CLK_OF_DECLARE(qoriq_clockgen_ls1043a, "fsl,ls1043a-clockgen", clockgen_init);
1278CLK_OF_DECLARE(qoriq_clockgen_ls2080a, "fsl,ls2080a-clockgen", clockgen_init);
1279
1280/* Legacy nodes */
1281CLK_OF_DECLARE(qoriq_sysclk_1, "fsl,qoriq-sysclk-1.0", sysclk_init);
1282CLK_OF_DECLARE(qoriq_sysclk_2, "fsl,qoriq-sysclk-2.0", sysclk_init);
1283CLK_OF_DECLARE(qoriq_core_pll_1, "fsl,qoriq-core-pll-1.0", core_pll_init);
1284CLK_OF_DECLARE(qoriq_core_pll_2, "fsl,qoriq-core-pll-2.0", core_pll_init);
1285CLK_OF_DECLARE(qoriq_core_mux_1, "fsl,qoriq-core-mux-1.0", core_mux_init);
1286CLK_OF_DECLARE(qoriq_core_mux_2, "fsl,qoriq-core-mux-2.0", core_mux_init);
1287CLK_OF_DECLARE(qoriq_pltfrm_pll_1, "fsl,qoriq-platform-pll-1.0", pltfrm_pll_init);
1288CLK_OF_DECLARE(qoriq_pltfrm_pll_2, "fsl,qoriq-platform-pll-2.0", pltfrm_pll_init);
1289