747 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * clk-xgene.c - AppliedMicro X-Gene Clock Interface4 *5 * Copyright (c) 2013, Applied Micro Circuits Corporation6 * Author: Loc Ho <lho@apm.com>7 */8#include <linux/module.h>9#include <linux/spinlock.h>10#include <linux/io.h>11#include <linux/of.h>12#include <linux/clkdev.h>13#include <linux/clk-provider.h>14#include <linux/of_address.h>15 16/* Register SCU_PCPPLL bit fields */17#define N_DIV_RD(src) ((src) & 0x000001ff)18#define SC_N_DIV_RD(src) ((src) & 0x0000007f)19#define SC_OUTDIV2(src) (((src) & 0x00000100) >> 8)20 21/* Register SCU_SOCPLL bit fields */22#define CLKR_RD(src) (((src) & 0x07000000)>>24)23#define CLKOD_RD(src) (((src) & 0x00300000)>>20)24#define REGSPEC_RESET_F1_MASK 0x0001000025#define CLKF_RD(src) (((src) & 0x000001ff))26 27#define XGENE_CLK_DRIVER_VER "0.1"28 29static DEFINE_SPINLOCK(clk_lock);30 31static inline u32 xgene_clk_read(void __iomem *csr)32{33 return readl_relaxed(csr);34}35 36static inline void xgene_clk_write(u32 data, void __iomem *csr)37{38 writel_relaxed(data, csr);39}40 41/* PLL Clock */42enum xgene_pll_type {43 PLL_TYPE_PCP = 0,44 PLL_TYPE_SOC = 1,45};46 47struct xgene_clk_pll {48 struct clk_hw hw;49 void __iomem *reg;50 spinlock_t *lock;51 u32 pll_offset;52 enum xgene_pll_type type;53 int version;54};55 56#define to_xgene_clk_pll(_hw) container_of(_hw, struct xgene_clk_pll, hw)57 58static int xgene_clk_pll_is_enabled(struct clk_hw *hw)59{60 struct xgene_clk_pll *pllclk = to_xgene_clk_pll(hw);61 u32 data;62 63 data = xgene_clk_read(pllclk->reg + pllclk->pll_offset);64 pr_debug("%s pll %s\n", clk_hw_get_name(hw),65 data & REGSPEC_RESET_F1_MASK ? "disabled" : "enabled");66 67 return data & REGSPEC_RESET_F1_MASK ? 0 : 1;68}69 70static unsigned long xgene_clk_pll_recalc_rate(struct clk_hw *hw,71 unsigned long parent_rate)72{73 struct xgene_clk_pll *pllclk = to_xgene_clk_pll(hw);74 unsigned long fref;75 unsigned long fvco;76 u32 pll;77 u32 nref;78 u32 nout;79 u32 nfb;80 81 pll = xgene_clk_read(pllclk->reg + pllclk->pll_offset);82 83 if (pllclk->version <= 1) {84 if (pllclk->type == PLL_TYPE_PCP) {85 /*86 * PLL VCO = Reference clock * NF87 * PCP PLL = PLL_VCO / 288 */89 nout = 2;90 fvco = parent_rate * (N_DIV_RD(pll) + 4);91 } else {92 /*93 * Fref = Reference Clock / NREF;94 * Fvco = Fref * NFB;95 * Fout = Fvco / NOUT;96 */97 nref = CLKR_RD(pll) + 1;98 nout = CLKOD_RD(pll) + 1;99 nfb = CLKF_RD(pll);100 fref = parent_rate / nref;101 fvco = fref * nfb;102 }103 } else {104 /*105 * fvco = Reference clock * FBDIVC106 * PLL freq = fvco / NOUT107 */108 nout = SC_OUTDIV2(pll) ? 2 : 3;109 fvco = parent_rate * SC_N_DIV_RD(pll);110 }111 pr_debug("%s pll recalc rate %ld parent %ld version %d\n",112 clk_hw_get_name(hw), fvco / nout, parent_rate,113 pllclk->version);114 115 return fvco / nout;116}117 118static const struct clk_ops xgene_clk_pll_ops = {119 .is_enabled = xgene_clk_pll_is_enabled,120 .recalc_rate = xgene_clk_pll_recalc_rate,121};122 123static struct clk *xgene_register_clk_pll(struct device *dev,124 const char *name, const char *parent_name,125 unsigned long flags, void __iomem *reg, u32 pll_offset,126 u32 type, spinlock_t *lock, int version)127{128 struct xgene_clk_pll *apmclk;129 struct clk *clk;130 struct clk_init_data init;131 132 /* allocate the APM clock structure */133 apmclk = kzalloc(sizeof(*apmclk), GFP_KERNEL);134 if (!apmclk)135 return ERR_PTR(-ENOMEM);136 137 init.name = name;138 init.ops = &xgene_clk_pll_ops;139 init.flags = flags;140 init.parent_names = parent_name ? &parent_name : NULL;141 init.num_parents = parent_name ? 1 : 0;142 143 apmclk->version = version;144 apmclk->reg = reg;145 apmclk->lock = lock;146 apmclk->pll_offset = pll_offset;147 apmclk->type = type;148 apmclk->hw.init = &init;149 150 /* Register the clock */151 clk = clk_register(dev, &apmclk->hw);152 if (IS_ERR(clk)) {153 pr_err("%s: could not register clk %s\n", __func__, name);154 kfree(apmclk);155 return NULL;156 }157 return clk;158}159 160static int xgene_pllclk_version(struct device_node *np)161{162 if (of_device_is_compatible(np, "apm,xgene-socpll-clock"))163 return 1;164 if (of_device_is_compatible(np, "apm,xgene-pcppll-clock"))165 return 1;166 return 2;167}168 169static void xgene_pllclk_init(struct device_node *np, enum xgene_pll_type pll_type)170{171 const char *clk_name = np->full_name;172 struct clk *clk;173 void __iomem *reg;174 int version = xgene_pllclk_version(np);175 176 reg = of_iomap(np, 0);177 if (!reg) {178 pr_err("Unable to map CSR register for %pOF\n", np);179 return;180 }181 of_property_read_string(np, "clock-output-names", &clk_name);182 clk = xgene_register_clk_pll(NULL,183 clk_name, of_clk_get_parent_name(np, 0),184 0, reg, 0, pll_type, &clk_lock,185 version);186 if (!IS_ERR(clk)) {187 of_clk_add_provider(np, of_clk_src_simple_get, clk);188 clk_register_clkdev(clk, clk_name, NULL);189 pr_debug("Add %s clock PLL\n", clk_name);190 }191}192 193static void xgene_socpllclk_init(struct device_node *np)194{195 xgene_pllclk_init(np, PLL_TYPE_SOC);196}197 198static void xgene_pcppllclk_init(struct device_node *np)199{200 xgene_pllclk_init(np, PLL_TYPE_PCP);201}202 203/**204 * struct xgene_clk_pmd - PMD clock205 *206 * @hw: handle between common and hardware-specific interfaces207 * @reg: register containing the fractional scale multiplier (scaler)208 * @shift: shift to the unit bit field209 * @mask: mask to the unit bit field210 * @denom: 1/denominator unit211 * @lock: register lock212 * @flags: XGENE_CLK_PMD_SCALE_INVERTED - By default the scaler is the value read213 * from the register plus one. For example,214 * 0 for (0 + 1) / denom,215 * 1 for (1 + 1) / denom and etc.216 * If this flag is set, it is217 * 0 for (denom - 0) / denom,218 * 1 for (denom - 1) / denom and etc.219 */220struct xgene_clk_pmd {221 struct clk_hw hw;222 void __iomem *reg;223 u8 shift;224 u32 mask;225 u64 denom;226 u32 flags;227 spinlock_t *lock;228};229 230#define to_xgene_clk_pmd(_hw) container_of(_hw, struct xgene_clk_pmd, hw)231 232#define XGENE_CLK_PMD_SCALE_INVERTED BIT(0)233#define XGENE_CLK_PMD_SHIFT 8234#define XGENE_CLK_PMD_WIDTH 3235 236static unsigned long xgene_clk_pmd_recalc_rate(struct clk_hw *hw,237 unsigned long parent_rate)238{239 struct xgene_clk_pmd *fd = to_xgene_clk_pmd(hw);240 unsigned long flags = 0;241 u64 ret, scale;242 u32 val;243 244 if (fd->lock)245 spin_lock_irqsave(fd->lock, flags);246 else247 __acquire(fd->lock);248 249 val = readl(fd->reg);250 251 if (fd->lock)252 spin_unlock_irqrestore(fd->lock, flags);253 else254 __release(fd->lock);255 256 ret = (u64)parent_rate;257 258 scale = (val & fd->mask) >> fd->shift;259 if (fd->flags & XGENE_CLK_PMD_SCALE_INVERTED)260 scale = fd->denom - scale;261 else262 scale++;263 264 /* freq = parent_rate * scaler / denom */265 do_div(ret, fd->denom);266 ret *= scale;267 if (ret == 0)268 ret = (u64)parent_rate;269 270 return ret;271}272 273static long xgene_clk_pmd_round_rate(struct clk_hw *hw, unsigned long rate,274 unsigned long *parent_rate)275{276 struct xgene_clk_pmd *fd = to_xgene_clk_pmd(hw);277 u64 ret, scale;278 279 if (!rate || rate >= *parent_rate)280 return *parent_rate;281 282 /* freq = parent_rate * scaler / denom */283 ret = rate * fd->denom;284 scale = DIV_ROUND_UP_ULL(ret, *parent_rate);285 286 ret = (u64)*parent_rate * scale;287 do_div(ret, fd->denom);288 289 return ret;290}291 292static int xgene_clk_pmd_set_rate(struct clk_hw *hw, unsigned long rate,293 unsigned long parent_rate)294{295 struct xgene_clk_pmd *fd = to_xgene_clk_pmd(hw);296 unsigned long flags = 0;297 u64 scale, ret;298 u32 val;299 300 /*301 * Compute the scaler:302 *303 * freq = parent_rate * scaler / denom, or304 * scaler = freq * denom / parent_rate305 */306 ret = rate * fd->denom;307 scale = DIV_ROUND_UP_ULL(ret, (u64)parent_rate);308 309 /* Check if inverted */310 if (fd->flags & XGENE_CLK_PMD_SCALE_INVERTED)311 scale = fd->denom - scale;312 else313 scale--;314 315 if (fd->lock)316 spin_lock_irqsave(fd->lock, flags);317 else318 __acquire(fd->lock);319 320 val = readl(fd->reg);321 val &= ~fd->mask;322 val |= (scale << fd->shift);323 writel(val, fd->reg);324 325 if (fd->lock)326 spin_unlock_irqrestore(fd->lock, flags);327 else328 __release(fd->lock);329 330 return 0;331}332 333static const struct clk_ops xgene_clk_pmd_ops = {334 .recalc_rate = xgene_clk_pmd_recalc_rate,335 .round_rate = xgene_clk_pmd_round_rate,336 .set_rate = xgene_clk_pmd_set_rate,337};338 339static struct clk *340xgene_register_clk_pmd(struct device *dev,341 const char *name, const char *parent_name,342 unsigned long flags, void __iomem *reg, u8 shift,343 u8 width, u64 denom, u32 clk_flags, spinlock_t *lock)344{345 struct xgene_clk_pmd *fd;346 struct clk_init_data init;347 struct clk *clk;348 349 fd = kzalloc(sizeof(*fd), GFP_KERNEL);350 if (!fd)351 return ERR_PTR(-ENOMEM);352 353 init.name = name;354 init.ops = &xgene_clk_pmd_ops;355 init.flags = flags;356 init.parent_names = parent_name ? &parent_name : NULL;357 init.num_parents = parent_name ? 1 : 0;358 359 fd->reg = reg;360 fd->shift = shift;361 fd->mask = (BIT(width) - 1) << shift;362 fd->denom = denom;363 fd->flags = clk_flags;364 fd->lock = lock;365 fd->hw.init = &init;366 367 clk = clk_register(dev, &fd->hw);368 if (IS_ERR(clk)) {369 pr_err("%s: could not register clk %s\n", __func__, name);370 kfree(fd);371 return NULL;372 }373 374 return clk;375}376 377static void xgene_pmdclk_init(struct device_node *np)378{379 const char *clk_name = np->full_name;380 void __iomem *csr_reg;381 struct resource res;382 struct clk *clk;383 u64 denom;384 u32 flags = 0;385 int rc;386 387 /* Check if the entry is disabled */388 if (!of_device_is_available(np))389 return;390 391 /* Parse the DTS register for resource */392 rc = of_address_to_resource(np, 0, &res);393 if (rc != 0) {394 pr_err("no DTS register for %pOF\n", np);395 return;396 }397 csr_reg = of_iomap(np, 0);398 if (!csr_reg) {399 pr_err("Unable to map resource for %pOF\n", np);400 return;401 }402 of_property_read_string(np, "clock-output-names", &clk_name);403 404 denom = BIT(XGENE_CLK_PMD_WIDTH);405 flags |= XGENE_CLK_PMD_SCALE_INVERTED;406 407 clk = xgene_register_clk_pmd(NULL, clk_name,408 of_clk_get_parent_name(np, 0), 0,409 csr_reg, XGENE_CLK_PMD_SHIFT,410 XGENE_CLK_PMD_WIDTH, denom,411 flags, &clk_lock);412 if (!IS_ERR(clk)) {413 of_clk_add_provider(np, of_clk_src_simple_get, clk);414 clk_register_clkdev(clk, clk_name, NULL);415 pr_debug("Add %s clock\n", clk_name);416 } else {417 if (csr_reg)418 iounmap(csr_reg);419 }420}421 422/* IP Clock */423struct xgene_dev_parameters {424 void __iomem *csr_reg; /* CSR for IP clock */425 u32 reg_clk_offset; /* Offset to clock enable CSR */426 u32 reg_clk_mask; /* Mask bit for clock enable */427 u32 reg_csr_offset; /* Offset to CSR reset */428 u32 reg_csr_mask; /* Mask bit for disable CSR reset */429 void __iomem *divider_reg; /* CSR for divider */430 u32 reg_divider_offset; /* Offset to divider register */431 u32 reg_divider_shift; /* Bit shift to divider field */432 u32 reg_divider_width; /* Width of the bit to divider field */433};434 435struct xgene_clk {436 struct clk_hw hw;437 spinlock_t *lock;438 struct xgene_dev_parameters param;439};440 441#define to_xgene_clk(_hw) container_of(_hw, struct xgene_clk, hw)442 443static int xgene_clk_enable(struct clk_hw *hw)444{445 struct xgene_clk *pclk = to_xgene_clk(hw);446 unsigned long flags = 0;447 u32 data;448 449 if (pclk->lock)450 spin_lock_irqsave(pclk->lock, flags);451 452 if (pclk->param.csr_reg) {453 pr_debug("%s clock enabled\n", clk_hw_get_name(hw));454 /* First enable the clock */455 data = xgene_clk_read(pclk->param.csr_reg +456 pclk->param.reg_clk_offset);457 data |= pclk->param.reg_clk_mask;458 xgene_clk_write(data, pclk->param.csr_reg +459 pclk->param.reg_clk_offset);460 pr_debug("%s clk offset 0x%08X mask 0x%08X value 0x%08X\n",461 clk_hw_get_name(hw),462 pclk->param.reg_clk_offset, pclk->param.reg_clk_mask,463 data);464 465 /* Second enable the CSR */466 data = xgene_clk_read(pclk->param.csr_reg +467 pclk->param.reg_csr_offset);468 data &= ~pclk->param.reg_csr_mask;469 xgene_clk_write(data, pclk->param.csr_reg +470 pclk->param.reg_csr_offset);471 pr_debug("%s csr offset 0x%08X mask 0x%08X value 0x%08X\n",472 clk_hw_get_name(hw),473 pclk->param.reg_csr_offset, pclk->param.reg_csr_mask,474 data);475 }476 477 if (pclk->lock)478 spin_unlock_irqrestore(pclk->lock, flags);479 480 return 0;481}482 483static void xgene_clk_disable(struct clk_hw *hw)484{485 struct xgene_clk *pclk = to_xgene_clk(hw);486 unsigned long flags = 0;487 u32 data;488 489 if (pclk->lock)490 spin_lock_irqsave(pclk->lock, flags);491 492 if (pclk->param.csr_reg) {493 pr_debug("%s clock disabled\n", clk_hw_get_name(hw));494 /* First put the CSR in reset */495 data = xgene_clk_read(pclk->param.csr_reg +496 pclk->param.reg_csr_offset);497 data |= pclk->param.reg_csr_mask;498 xgene_clk_write(data, pclk->param.csr_reg +499 pclk->param.reg_csr_offset);500 501 /* Second disable the clock */502 data = xgene_clk_read(pclk->param.csr_reg +503 pclk->param.reg_clk_offset);504 data &= ~pclk->param.reg_clk_mask;505 xgene_clk_write(data, pclk->param.csr_reg +506 pclk->param.reg_clk_offset);507 }508 509 if (pclk->lock)510 spin_unlock_irqrestore(pclk->lock, flags);511}512 513static int xgene_clk_is_enabled(struct clk_hw *hw)514{515 struct xgene_clk *pclk = to_xgene_clk(hw);516 u32 data = 0;517 518 if (pclk->param.csr_reg) {519 pr_debug("%s clock checking\n", clk_hw_get_name(hw));520 data = xgene_clk_read(pclk->param.csr_reg +521 pclk->param.reg_clk_offset);522 pr_debug("%s clock is %s\n", clk_hw_get_name(hw),523 data & pclk->param.reg_clk_mask ? "enabled" :524 "disabled");525 } else {526 return 1;527 }528 529 return data & pclk->param.reg_clk_mask ? 1 : 0;530}531 532static unsigned long xgene_clk_recalc_rate(struct clk_hw *hw,533 unsigned long parent_rate)534{535 struct xgene_clk *pclk = to_xgene_clk(hw);536 u32 data;537 538 if (pclk->param.divider_reg) {539 data = xgene_clk_read(pclk->param.divider_reg +540 pclk->param.reg_divider_offset);541 data >>= pclk->param.reg_divider_shift;542 data &= (1 << pclk->param.reg_divider_width) - 1;543 544 pr_debug("%s clock recalc rate %ld parent %ld\n",545 clk_hw_get_name(hw),546 parent_rate / data, parent_rate);547 548 return parent_rate / data;549 } else {550 pr_debug("%s clock recalc rate %ld parent %ld\n",551 clk_hw_get_name(hw), parent_rate, parent_rate);552 return parent_rate;553 }554}555 556static int xgene_clk_set_rate(struct clk_hw *hw, unsigned long rate,557 unsigned long parent_rate)558{559 struct xgene_clk *pclk = to_xgene_clk(hw);560 unsigned long flags = 0;561 u32 data;562 u32 divider;563 u32 divider_save;564 565 if (pclk->lock)566 spin_lock_irqsave(pclk->lock, flags);567 568 if (pclk->param.divider_reg) {569 /* Let's compute the divider */570 if (rate > parent_rate)571 rate = parent_rate;572 divider_save = divider = parent_rate / rate; /* Rounded down */573 divider &= (1 << pclk->param.reg_divider_width) - 1;574 divider <<= pclk->param.reg_divider_shift;575 576 /* Set new divider */577 data = xgene_clk_read(pclk->param.divider_reg +578 pclk->param.reg_divider_offset);579 data &= ~(((1 << pclk->param.reg_divider_width) - 1)580 << pclk->param.reg_divider_shift);581 data |= divider;582 xgene_clk_write(data, pclk->param.divider_reg +583 pclk->param.reg_divider_offset);584 pr_debug("%s clock set rate %ld\n", clk_hw_get_name(hw),585 parent_rate / divider_save);586 } else {587 divider_save = 1;588 }589 590 if (pclk->lock)591 spin_unlock_irqrestore(pclk->lock, flags);592 593 return parent_rate / divider_save;594}595 596static long xgene_clk_round_rate(struct clk_hw *hw, unsigned long rate,597 unsigned long *prate)598{599 struct xgene_clk *pclk = to_xgene_clk(hw);600 unsigned long parent_rate = *prate;601 u32 divider;602 603 if (pclk->param.divider_reg) {604 /* Let's compute the divider */605 if (rate > parent_rate)606 rate = parent_rate;607 divider = parent_rate / rate; /* Rounded down */608 } else {609 divider = 1;610 }611 612 return parent_rate / divider;613}614 615static const struct clk_ops xgene_clk_ops = {616 .enable = xgene_clk_enable,617 .disable = xgene_clk_disable,618 .is_enabled = xgene_clk_is_enabled,619 .recalc_rate = xgene_clk_recalc_rate,620 .set_rate = xgene_clk_set_rate,621 .round_rate = xgene_clk_round_rate,622};623 624static struct clk *xgene_register_clk(struct device *dev,625 const char *name, const char *parent_name,626 struct xgene_dev_parameters *parameters, spinlock_t *lock)627{628 struct xgene_clk *apmclk;629 struct clk *clk;630 struct clk_init_data init;631 int rc;632 633 /* allocate the APM clock structure */634 apmclk = kzalloc(sizeof(*apmclk), GFP_KERNEL);635 if (!apmclk)636 return ERR_PTR(-ENOMEM);637 638 init.name = name;639 init.ops = &xgene_clk_ops;640 init.flags = 0;641 init.parent_names = parent_name ? &parent_name : NULL;642 init.num_parents = parent_name ? 1 : 0;643 644 apmclk->lock = lock;645 apmclk->hw.init = &init;646 apmclk->param = *parameters;647 648 /* Register the clock */649 clk = clk_register(dev, &apmclk->hw);650 if (IS_ERR(clk)) {651 pr_err("%s: could not register clk %s\n", __func__, name);652 kfree(apmclk);653 return clk;654 }655 656 /* Register the clock for lookup */657 rc = clk_register_clkdev(clk, name, NULL);658 if (rc != 0) {659 pr_err("%s: could not register lookup clk %s\n",660 __func__, name);661 }662 return clk;663}664 665static void __init xgene_devclk_init(struct device_node *np)666{667 const char *clk_name = np->full_name;668 struct clk *clk;669 struct resource res;670 int rc;671 struct xgene_dev_parameters parameters;672 int i;673 674 /* Check if the entry is disabled */675 if (!of_device_is_available(np))676 return;677 678 /* Parse the DTS register for resource */679 parameters.csr_reg = NULL;680 parameters.divider_reg = NULL;681 for (i = 0; i < 2; i++) {682 void __iomem *map_res;683 rc = of_address_to_resource(np, i, &res);684 if (rc != 0) {685 if (i == 0) {686 pr_err("no DTS register for %pOF\n", np);687 return;688 }689 break;690 }691 map_res = of_iomap(np, i);692 if (!map_res) {693 pr_err("Unable to map resource %d for %pOF\n", i, np);694 goto err;695 }696 if (strcmp(res.name, "div-reg") == 0)697 parameters.divider_reg = map_res;698 else /* if (strcmp(res->name, "csr-reg") == 0) */699 parameters.csr_reg = map_res;700 }701 if (of_property_read_u32(np, "csr-offset", ¶meters.reg_csr_offset))702 parameters.reg_csr_offset = 0;703 if (of_property_read_u32(np, "csr-mask", ¶meters.reg_csr_mask))704 parameters.reg_csr_mask = 0xF;705 if (of_property_read_u32(np, "enable-offset",706 ¶meters.reg_clk_offset))707 parameters.reg_clk_offset = 0x8;708 if (of_property_read_u32(np, "enable-mask", ¶meters.reg_clk_mask))709 parameters.reg_clk_mask = 0xF;710 if (of_property_read_u32(np, "divider-offset",711 ¶meters.reg_divider_offset))712 parameters.reg_divider_offset = 0;713 if (of_property_read_u32(np, "divider-width",714 ¶meters.reg_divider_width))715 parameters.reg_divider_width = 0;716 if (of_property_read_u32(np, "divider-shift",717 ¶meters.reg_divider_shift))718 parameters.reg_divider_shift = 0;719 of_property_read_string(np, "clock-output-names", &clk_name);720 721 clk = xgene_register_clk(NULL, clk_name,722 of_clk_get_parent_name(np, 0), ¶meters, &clk_lock);723 if (IS_ERR(clk))724 goto err;725 pr_debug("Add %s clock\n", clk_name);726 rc = of_clk_add_provider(np, of_clk_src_simple_get, clk);727 if (rc != 0)728 pr_err("%s: could register provider clk %pOF\n", __func__, np);729 730 return;731 732err:733 if (parameters.csr_reg)734 iounmap(parameters.csr_reg);735 if (parameters.divider_reg)736 iounmap(parameters.divider_reg);737}738 739CLK_OF_DECLARE(xgene_socpll_clock, "apm,xgene-socpll-clock", xgene_socpllclk_init);740CLK_OF_DECLARE(xgene_pcppll_clock, "apm,xgene-pcppll-clock", xgene_pcppllclk_init);741CLK_OF_DECLARE(xgene_pmd_clock, "apm,xgene-pmd-clock", xgene_pmdclk_init);742CLK_OF_DECLARE(xgene_socpll_v2_clock, "apm,xgene-socpll-v2-clock",743 xgene_socpllclk_init);744CLK_OF_DECLARE(xgene_pcppll_v2_clock, "apm,xgene-pcppll-v2-clock",745 xgene_pcppllclk_init);746CLK_OF_DECLARE(xgene_dev_clock, "apm,xgene-device-clock", xgene_devclk_init);747