667 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Clk driver for NXP LPC18xx/LPC43xx Clock Generation Unit (CGU)4 *5 * Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com>6 */7 8#include <linux/clk-provider.h>9#include <linux/delay.h>10#include <linux/io.h>11#include <linux/kernel.h>12#include <linux/of.h>13#include <linux/of_address.h>14 15#include <dt-bindings/clock/lpc18xx-cgu.h>16 17/* Clock Generation Unit (CGU) registers */18#define LPC18XX_CGU_XTAL_OSC_CTRL 0x01819#define LPC18XX_CGU_PLL0USB_STAT 0x01c20#define LPC18XX_CGU_PLL0USB_CTRL 0x02021#define LPC18XX_CGU_PLL0USB_MDIV 0x02422#define LPC18XX_CGU_PLL0USB_NP_DIV 0x02823#define LPC18XX_CGU_PLL0AUDIO_STAT 0x02c24#define LPC18XX_CGU_PLL0AUDIO_CTRL 0x03025#define LPC18XX_CGU_PLL0AUDIO_MDIV 0x03426#define LPC18XX_CGU_PLL0AUDIO_NP_DIV 0x03827#define LPC18XX_CGU_PLL0AUDIO_FRAC 0x03c28#define LPC18XX_CGU_PLL1_STAT 0x04029#define LPC18XX_CGU_PLL1_CTRL 0x04430#define LPC18XX_PLL1_CTRL_FBSEL BIT(6)31#define LPC18XX_PLL1_CTRL_DIRECT BIT(7)32#define LPC18XX_CGU_IDIV_CTRL(n) (0x048 + (n) * sizeof(u32))33#define LPC18XX_CGU_BASE_CLK(id) (0x05c + (id) * sizeof(u32))34#define LPC18XX_CGU_PLL_CTRL_OFFSET 0x435 36/* PLL0 bits common to both audio and USB PLL */37#define LPC18XX_PLL0_STAT_LOCK BIT(0)38#define LPC18XX_PLL0_CTRL_PD BIT(0)39#define LPC18XX_PLL0_CTRL_BYPASS BIT(1)40#define LPC18XX_PLL0_CTRL_DIRECTI BIT(2)41#define LPC18XX_PLL0_CTRL_DIRECTO BIT(3)42#define LPC18XX_PLL0_CTRL_CLKEN BIT(4)43#define LPC18XX_PLL0_MDIV_MDEC_MASK 0x1ffff44#define LPC18XX_PLL0_MDIV_SELP_SHIFT 1745#define LPC18XX_PLL0_MDIV_SELI_SHIFT 2246#define LPC18XX_PLL0_MSEL_MAX BIT(15)47 48/* Register value that gives PLL0 post/pre dividers equal to 1 */49#define LPC18XX_PLL0_NP_DIVS_1 0x0030206250 51enum {52 CLK_SRC_OSC32,53 CLK_SRC_IRC,54 CLK_SRC_ENET_RX_CLK,55 CLK_SRC_ENET_TX_CLK,56 CLK_SRC_GP_CLKIN,57 CLK_SRC_RESERVED1,58 CLK_SRC_OSC,59 CLK_SRC_PLL0USB,60 CLK_SRC_PLL0AUDIO,61 CLK_SRC_PLL1,62 CLK_SRC_RESERVED2,63 CLK_SRC_RESERVED3,64 CLK_SRC_IDIVA,65 CLK_SRC_IDIVB,66 CLK_SRC_IDIVC,67 CLK_SRC_IDIVD,68 CLK_SRC_IDIVE,69 CLK_SRC_MAX70};71 72static const char *clk_src_names[CLK_SRC_MAX] = {73 [CLK_SRC_OSC32] = "osc32",74 [CLK_SRC_IRC] = "irc",75 [CLK_SRC_ENET_RX_CLK] = "enet_rx_clk",76 [CLK_SRC_ENET_TX_CLK] = "enet_tx_clk",77 [CLK_SRC_GP_CLKIN] = "gp_clkin",78 [CLK_SRC_OSC] = "osc",79 [CLK_SRC_PLL0USB] = "pll0usb",80 [CLK_SRC_PLL0AUDIO] = "pll0audio",81 [CLK_SRC_PLL1] = "pll1",82 [CLK_SRC_IDIVA] = "idiva",83 [CLK_SRC_IDIVB] = "idivb",84 [CLK_SRC_IDIVC] = "idivc",85 [CLK_SRC_IDIVD] = "idivd",86 [CLK_SRC_IDIVE] = "idive",87};88 89static const char *clk_base_names[BASE_CLK_MAX] = {90 [BASE_SAFE_CLK] = "base_safe_clk",91 [BASE_USB0_CLK] = "base_usb0_clk",92 [BASE_PERIPH_CLK] = "base_periph_clk",93 [BASE_USB1_CLK] = "base_usb1_clk",94 [BASE_CPU_CLK] = "base_cpu_clk",95 [BASE_SPIFI_CLK] = "base_spifi_clk",96 [BASE_SPI_CLK] = "base_spi_clk",97 [BASE_PHY_RX_CLK] = "base_phy_rx_clk",98 [BASE_PHY_TX_CLK] = "base_phy_tx_clk",99 [BASE_APB1_CLK] = "base_apb1_clk",100 [BASE_APB3_CLK] = "base_apb3_clk",101 [BASE_LCD_CLK] = "base_lcd_clk",102 [BASE_ADCHS_CLK] = "base_adchs_clk",103 [BASE_SDIO_CLK] = "base_sdio_clk",104 [BASE_SSP0_CLK] = "base_ssp0_clk",105 [BASE_SSP1_CLK] = "base_ssp1_clk",106 [BASE_UART0_CLK] = "base_uart0_clk",107 [BASE_UART1_CLK] = "base_uart1_clk",108 [BASE_UART2_CLK] = "base_uart2_clk",109 [BASE_UART3_CLK] = "base_uart3_clk",110 [BASE_OUT_CLK] = "base_out_clk",111 [BASE_AUDIO_CLK] = "base_audio_clk",112 [BASE_CGU_OUT0_CLK] = "base_cgu_out0_clk",113 [BASE_CGU_OUT1_CLK] = "base_cgu_out1_clk",114};115 116static u32 lpc18xx_cgu_pll0_src_ids[] = {117 CLK_SRC_OSC32, CLK_SRC_IRC, CLK_SRC_ENET_RX_CLK,118 CLK_SRC_ENET_TX_CLK, CLK_SRC_GP_CLKIN, CLK_SRC_OSC,119 CLK_SRC_PLL1, CLK_SRC_IDIVA, CLK_SRC_IDIVB, CLK_SRC_IDIVC,120 CLK_SRC_IDIVD, CLK_SRC_IDIVE,121};122 123static u32 lpc18xx_cgu_pll1_src_ids[] = {124 CLK_SRC_OSC32, CLK_SRC_IRC, CLK_SRC_ENET_RX_CLK,125 CLK_SRC_ENET_TX_CLK, CLK_SRC_GP_CLKIN, CLK_SRC_OSC,126 CLK_SRC_PLL0USB, CLK_SRC_PLL0AUDIO, CLK_SRC_IDIVA,127 CLK_SRC_IDIVB, CLK_SRC_IDIVC, CLK_SRC_IDIVD, CLK_SRC_IDIVE,128};129 130static u32 lpc18xx_cgu_idiva_src_ids[] = {131 CLK_SRC_OSC32, CLK_SRC_IRC, CLK_SRC_ENET_RX_CLK,132 CLK_SRC_ENET_TX_CLK, CLK_SRC_GP_CLKIN, CLK_SRC_OSC,133 CLK_SRC_PLL0USB, CLK_SRC_PLL0AUDIO, CLK_SRC_PLL1134};135 136static u32 lpc18xx_cgu_idivbcde_src_ids[] = {137 CLK_SRC_OSC32, CLK_SRC_IRC, CLK_SRC_ENET_RX_CLK,138 CLK_SRC_ENET_TX_CLK, CLK_SRC_GP_CLKIN, CLK_SRC_OSC,139 CLK_SRC_PLL0AUDIO, CLK_SRC_PLL1, CLK_SRC_IDIVA,140};141 142static u32 lpc18xx_cgu_base_irc_src_ids[] = {CLK_SRC_IRC};143 144static u32 lpc18xx_cgu_base_usb0_src_ids[] = {CLK_SRC_PLL0USB};145 146static u32 lpc18xx_cgu_base_common_src_ids[] = {147 CLK_SRC_OSC32, CLK_SRC_IRC, CLK_SRC_ENET_RX_CLK,148 CLK_SRC_ENET_TX_CLK, CLK_SRC_GP_CLKIN, CLK_SRC_OSC,149 CLK_SRC_PLL0AUDIO, CLK_SRC_PLL1, CLK_SRC_IDIVA,150 CLK_SRC_IDIVB, CLK_SRC_IDIVC, CLK_SRC_IDIVD, CLK_SRC_IDIVE,151};152 153static u32 lpc18xx_cgu_base_all_src_ids[] = {154 CLK_SRC_OSC32, CLK_SRC_IRC, CLK_SRC_ENET_RX_CLK,155 CLK_SRC_ENET_TX_CLK, CLK_SRC_GP_CLKIN, CLK_SRC_OSC,156 CLK_SRC_PLL0USB, CLK_SRC_PLL0AUDIO, CLK_SRC_PLL1,157 CLK_SRC_IDIVA, CLK_SRC_IDIVB, CLK_SRC_IDIVC,158 CLK_SRC_IDIVD, CLK_SRC_IDIVE,159};160 161struct lpc18xx_cgu_src_clk_div {162 u8 clk_id;163 u8 n_parents;164 struct clk_divider div;165 struct clk_mux mux;166 struct clk_gate gate;167};168 169#define LPC1XX_CGU_SRC_CLK_DIV(_id, _width, _table) \170{ \171 .clk_id = CLK_SRC_ ##_id, \172 .n_parents = ARRAY_SIZE(lpc18xx_cgu_ ##_table), \173 .div = { \174 .shift = 2, \175 .width = _width, \176 }, \177 .mux = { \178 .mask = 0x1f, \179 .shift = 24, \180 .table = lpc18xx_cgu_ ##_table, \181 }, \182 .gate = { \183 .bit_idx = 0, \184 .flags = CLK_GATE_SET_TO_DISABLE, \185 }, \186}187 188static struct lpc18xx_cgu_src_clk_div lpc18xx_cgu_src_clk_divs[] = {189 LPC1XX_CGU_SRC_CLK_DIV(IDIVA, 2, idiva_src_ids),190 LPC1XX_CGU_SRC_CLK_DIV(IDIVB, 4, idivbcde_src_ids),191 LPC1XX_CGU_SRC_CLK_DIV(IDIVC, 4, idivbcde_src_ids),192 LPC1XX_CGU_SRC_CLK_DIV(IDIVD, 4, idivbcde_src_ids),193 LPC1XX_CGU_SRC_CLK_DIV(IDIVE, 8, idivbcde_src_ids),194};195 196struct lpc18xx_cgu_base_clk {197 u8 clk_id;198 u8 n_parents;199 struct clk_mux mux;200 struct clk_gate gate;201};202 203#define LPC1XX_CGU_BASE_CLK(_id, _table, _flags) \204{ \205 .clk_id = BASE_ ##_id ##_CLK, \206 .n_parents = ARRAY_SIZE(lpc18xx_cgu_ ##_table), \207 .mux = { \208 .mask = 0x1f, \209 .shift = 24, \210 .table = lpc18xx_cgu_ ##_table, \211 .flags = _flags, \212 }, \213 .gate = { \214 .bit_idx = 0, \215 .flags = CLK_GATE_SET_TO_DISABLE, \216 }, \217}218 219static struct lpc18xx_cgu_base_clk lpc18xx_cgu_base_clks[] = {220 LPC1XX_CGU_BASE_CLK(SAFE, base_irc_src_ids, CLK_MUX_READ_ONLY),221 LPC1XX_CGU_BASE_CLK(USB0, base_usb0_src_ids, 0),222 LPC1XX_CGU_BASE_CLK(PERIPH, base_common_src_ids, 0),223 LPC1XX_CGU_BASE_CLK(USB1, base_all_src_ids, 0),224 LPC1XX_CGU_BASE_CLK(CPU, base_common_src_ids, 0),225 LPC1XX_CGU_BASE_CLK(SPIFI, base_common_src_ids, 0),226 LPC1XX_CGU_BASE_CLK(SPI, base_common_src_ids, 0),227 LPC1XX_CGU_BASE_CLK(PHY_RX, base_common_src_ids, 0),228 LPC1XX_CGU_BASE_CLK(PHY_TX, base_common_src_ids, 0),229 LPC1XX_CGU_BASE_CLK(APB1, base_common_src_ids, 0),230 LPC1XX_CGU_BASE_CLK(APB3, base_common_src_ids, 0),231 LPC1XX_CGU_BASE_CLK(LCD, base_common_src_ids, 0),232 LPC1XX_CGU_BASE_CLK(ADCHS, base_common_src_ids, 0),233 LPC1XX_CGU_BASE_CLK(SDIO, base_common_src_ids, 0),234 LPC1XX_CGU_BASE_CLK(SSP0, base_common_src_ids, 0),235 LPC1XX_CGU_BASE_CLK(SSP1, base_common_src_ids, 0),236 LPC1XX_CGU_BASE_CLK(UART0, base_common_src_ids, 0),237 LPC1XX_CGU_BASE_CLK(UART1, base_common_src_ids, 0),238 LPC1XX_CGU_BASE_CLK(UART2, base_common_src_ids, 0),239 LPC1XX_CGU_BASE_CLK(UART3, base_common_src_ids, 0),240 LPC1XX_CGU_BASE_CLK(OUT, base_all_src_ids, 0),241 { /* 21 reserved */ },242 { /* 22 reserved */ },243 { /* 23 reserved */ },244 { /* 24 reserved */ },245 LPC1XX_CGU_BASE_CLK(AUDIO, base_common_src_ids, 0),246 LPC1XX_CGU_BASE_CLK(CGU_OUT0, base_all_src_ids, 0),247 LPC1XX_CGU_BASE_CLK(CGU_OUT1, base_all_src_ids, 0),248};249 250struct lpc18xx_pll {251 struct clk_hw hw;252 void __iomem *reg;253 u8 flags;254};255 256#define to_lpc_pll(hw) container_of(hw, struct lpc18xx_pll, hw)257 258struct lpc18xx_cgu_pll_clk {259 u8 clk_id;260 u8 n_parents;261 u8 reg_offset;262 struct clk_mux mux;263 struct clk_gate gate;264 struct lpc18xx_pll pll;265 const struct clk_ops *pll_ops;266};267 268#define LPC1XX_CGU_CLK_PLL(_id, _table, _pll_ops) \269{ \270 .clk_id = CLK_SRC_ ##_id, \271 .n_parents = ARRAY_SIZE(lpc18xx_cgu_ ##_table), \272 .reg_offset = LPC18XX_CGU_ ##_id ##_STAT, \273 .mux = { \274 .mask = 0x1f, \275 .shift = 24, \276 .table = lpc18xx_cgu_ ##_table, \277 }, \278 .gate = { \279 .bit_idx = 0, \280 .flags = CLK_GATE_SET_TO_DISABLE, \281 }, \282 .pll_ops = &lpc18xx_ ##_pll_ops, \283}284 285/*286 * PLL0 uses a special register value encoding. The compute functions below287 * are taken or derived from the LPC1850 user manual (section 12.6.3.3).288 */289 290/* Compute PLL0 multiplier from decoded version */291static u32 lpc18xx_pll0_mdec2msel(u32 x)292{293 int i;294 295 switch (x) {296 case 0x18003: return 1;297 case 0x10003: return 2;298 default:299 for (i = LPC18XX_PLL0_MSEL_MAX + 1; x != 0x4000 && i > 0; i--)300 x = ((x ^ x >> 14) & 1) | (x << 1 & 0x7fff);301 return i;302 }303}304/* Compute PLL0 decoded multiplier from binary version */305static u32 lpc18xx_pll0_msel2mdec(u32 msel)306{307 u32 i, x = 0x4000;308 309 switch (msel) {310 case 0: return 0;311 case 1: return 0x18003;312 case 2: return 0x10003;313 default:314 for (i = msel; i <= LPC18XX_PLL0_MSEL_MAX; i++)315 x = ((x ^ x >> 1) & 1) << 14 | (x >> 1 & 0xffff);316 return x;317 }318}319 320/* Compute PLL0 bandwidth SELI reg from multiplier */321static u32 lpc18xx_pll0_msel2seli(u32 msel)322{323 u32 tmp;324 325 if (msel > 16384) return 1;326 if (msel > 8192) return 2;327 if (msel > 2048) return 4;328 if (msel >= 501) return 8;329 if (msel >= 60) {330 tmp = 1024 / (msel + 9);331 return ((1024 == (tmp * (msel + 9))) == 0) ? tmp * 4 : (tmp + 1) * 4;332 }333 334 return (msel & 0x3c) + 4;335}336 337/* Compute PLL0 bandwidth SELP reg from multiplier */338static u32 lpc18xx_pll0_msel2selp(u32 msel)339{340 if (msel < 60)341 return (msel >> 1) + 1;342 343 return 31;344}345 346static unsigned long lpc18xx_pll0_recalc_rate(struct clk_hw *hw,347 unsigned long parent_rate)348{349 struct lpc18xx_pll *pll = to_lpc_pll(hw);350 u32 ctrl, mdiv, msel, npdiv;351 352 ctrl = readl(pll->reg + LPC18XX_CGU_PLL0USB_CTRL);353 mdiv = readl(pll->reg + LPC18XX_CGU_PLL0USB_MDIV);354 npdiv = readl(pll->reg + LPC18XX_CGU_PLL0USB_NP_DIV);355 356 if (ctrl & LPC18XX_PLL0_CTRL_BYPASS)357 return parent_rate;358 359 if (npdiv != LPC18XX_PLL0_NP_DIVS_1) {360 pr_warn("%s: pre/post dividers not supported\n", __func__);361 return 0;362 }363 364 msel = lpc18xx_pll0_mdec2msel(mdiv & LPC18XX_PLL0_MDIV_MDEC_MASK);365 if (msel)366 return 2 * msel * parent_rate;367 368 pr_warn("%s: unable to calculate rate\n", __func__);369 370 return 0;371}372 373static long lpc18xx_pll0_round_rate(struct clk_hw *hw, unsigned long rate,374 unsigned long *prate)375{376 unsigned long m;377 378 if (*prate < rate) {379 pr_warn("%s: pll dividers not supported\n", __func__);380 return -EINVAL;381 }382 383 m = DIV_ROUND_UP_ULL(*prate, rate * 2);384 if (m <= 0 && m > LPC18XX_PLL0_MSEL_MAX) {385 pr_warn("%s: unable to support rate %lu\n", __func__, rate);386 return -EINVAL;387 }388 389 return 2 * *prate * m;390}391 392static int lpc18xx_pll0_set_rate(struct clk_hw *hw, unsigned long rate,393 unsigned long parent_rate)394{395 struct lpc18xx_pll *pll = to_lpc_pll(hw);396 u32 ctrl, stat, m;397 int retry = 3;398 399 if (parent_rate < rate) {400 pr_warn("%s: pll dividers not supported\n", __func__);401 return -EINVAL;402 }403 404 m = DIV_ROUND_UP_ULL(parent_rate, rate * 2);405 if (m <= 0 && m > LPC18XX_PLL0_MSEL_MAX) {406 pr_warn("%s: unable to support rate %lu\n", __func__, rate);407 return -EINVAL;408 }409 410 m = lpc18xx_pll0_msel2mdec(m);411 m |= lpc18xx_pll0_msel2selp(m) << LPC18XX_PLL0_MDIV_SELP_SHIFT;412 m |= lpc18xx_pll0_msel2seli(m) << LPC18XX_PLL0_MDIV_SELI_SHIFT;413 414 /* Power down PLL, disable clk output and dividers */415 ctrl = readl(pll->reg + LPC18XX_CGU_PLL0USB_CTRL);416 ctrl |= LPC18XX_PLL0_CTRL_PD;417 ctrl &= ~(LPC18XX_PLL0_CTRL_BYPASS | LPC18XX_PLL0_CTRL_DIRECTI |418 LPC18XX_PLL0_CTRL_DIRECTO | LPC18XX_PLL0_CTRL_CLKEN);419 writel(ctrl, pll->reg + LPC18XX_CGU_PLL0USB_CTRL);420 421 /* Configure new PLL settings */422 writel(m, pll->reg + LPC18XX_CGU_PLL0USB_MDIV);423 writel(LPC18XX_PLL0_NP_DIVS_1, pll->reg + LPC18XX_CGU_PLL0USB_NP_DIV);424 425 /* Power up PLL and wait for lock */426 ctrl &= ~LPC18XX_PLL0_CTRL_PD;427 writel(ctrl, pll->reg + LPC18XX_CGU_PLL0USB_CTRL);428 do {429 udelay(10);430 stat = readl(pll->reg + LPC18XX_CGU_PLL0USB_STAT);431 if (stat & LPC18XX_PLL0_STAT_LOCK) {432 ctrl |= LPC18XX_PLL0_CTRL_CLKEN;433 writel(ctrl, pll->reg + LPC18XX_CGU_PLL0USB_CTRL);434 435 return 0;436 }437 } while (retry--);438 439 pr_warn("%s: unable to lock pll\n", __func__);440 441 return -EINVAL;442}443 444static const struct clk_ops lpc18xx_pll0_ops = {445 .recalc_rate = lpc18xx_pll0_recalc_rate,446 .round_rate = lpc18xx_pll0_round_rate,447 .set_rate = lpc18xx_pll0_set_rate,448};449 450static unsigned long lpc18xx_pll1_recalc_rate(struct clk_hw *hw,451 unsigned long parent_rate)452{453 struct lpc18xx_pll *pll = to_lpc_pll(hw);454 u16 msel, nsel, psel;455 bool direct, fbsel;456 u32 ctrl;457 458 ctrl = readl(pll->reg + LPC18XX_CGU_PLL1_CTRL);459 460 direct = (ctrl & LPC18XX_PLL1_CTRL_DIRECT) ? true : false;461 fbsel = (ctrl & LPC18XX_PLL1_CTRL_FBSEL) ? true : false;462 463 msel = ((ctrl >> 16) & 0xff) + 1;464 nsel = ((ctrl >> 12) & 0x3) + 1;465 466 if (direct || fbsel)467 return msel * (parent_rate / nsel);468 469 psel = (ctrl >> 8) & 0x3;470 psel = 1 << psel;471 472 return (msel / (2 * psel)) * (parent_rate / nsel);473}474 475static const struct clk_ops lpc18xx_pll1_ops = {476 .recalc_rate = lpc18xx_pll1_recalc_rate,477};478 479static int lpc18xx_cgu_gate_enable(struct clk_hw *hw)480{481 return clk_gate_ops.enable(hw);482}483 484static void lpc18xx_cgu_gate_disable(struct clk_hw *hw)485{486 clk_gate_ops.disable(hw);487}488 489static int lpc18xx_cgu_gate_is_enabled(struct clk_hw *hw)490{491 const struct clk_hw *parent;492 493 /*494 * The consumer of base clocks needs know if the495 * base clock is really enabled before it can be496 * accessed. It is therefore necessary to verify497 * this all the way up.498 */499 parent = clk_hw_get_parent(hw);500 if (!parent)501 return 0;502 503 if (!clk_hw_is_enabled(parent))504 return 0;505 506 return clk_gate_ops.is_enabled(hw);507}508 509static const struct clk_ops lpc18xx_gate_ops = {510 .enable = lpc18xx_cgu_gate_enable,511 .disable = lpc18xx_cgu_gate_disable,512 .is_enabled = lpc18xx_cgu_gate_is_enabled,513};514 515static struct lpc18xx_cgu_pll_clk lpc18xx_cgu_src_clk_plls[] = {516 LPC1XX_CGU_CLK_PLL(PLL0USB, pll0_src_ids, pll0_ops),517 LPC1XX_CGU_CLK_PLL(PLL0AUDIO, pll0_src_ids, pll0_ops),518 LPC1XX_CGU_CLK_PLL(PLL1, pll1_src_ids, pll1_ops),519};520 521static void lpc18xx_fill_parent_names(const char **parent, const u32 *id, int size)522{523 int i;524 525 for (i = 0; i < size; i++)526 parent[i] = clk_src_names[id[i]];527}528 529static struct clk *lpc18xx_cgu_register_div(struct lpc18xx_cgu_src_clk_div *clk,530 void __iomem *base, int n)531{532 void __iomem *reg = base + LPC18XX_CGU_IDIV_CTRL(n);533 const char *name = clk_src_names[clk->clk_id];534 const char *parents[CLK_SRC_MAX];535 536 clk->div.reg = reg;537 clk->mux.reg = reg;538 clk->gate.reg = reg;539 540 lpc18xx_fill_parent_names(parents, clk->mux.table, clk->n_parents);541 542 return clk_register_composite(NULL, name, parents, clk->n_parents,543 &clk->mux.hw, &clk_mux_ops,544 &clk->div.hw, &clk_divider_ops,545 &clk->gate.hw, &lpc18xx_gate_ops, 0);546}547 548 549static struct clk *lpc18xx_register_base_clk(struct lpc18xx_cgu_base_clk *clk,550 void __iomem *reg_base, int n)551{552 void __iomem *reg = reg_base + LPC18XX_CGU_BASE_CLK(n);553 const char *name = clk_base_names[clk->clk_id];554 const char *parents[CLK_SRC_MAX];555 556 if (clk->n_parents == 0)557 return ERR_PTR(-ENOENT);558 559 clk->mux.reg = reg;560 clk->gate.reg = reg;561 562 lpc18xx_fill_parent_names(parents, clk->mux.table, clk->n_parents);563 564 /* SAFE_CLK can not be turned off */565 if (n == BASE_SAFE_CLK)566 return clk_register_composite(NULL, name, parents, clk->n_parents,567 &clk->mux.hw, &clk_mux_ops,568 NULL, NULL, NULL, NULL, 0);569 570 return clk_register_composite(NULL, name, parents, clk->n_parents,571 &clk->mux.hw, &clk_mux_ops,572 NULL, NULL,573 &clk->gate.hw, &lpc18xx_gate_ops, 0);574}575 576 577static struct clk *lpc18xx_cgu_register_pll(struct lpc18xx_cgu_pll_clk *clk,578 void __iomem *base)579{580 const char *name = clk_src_names[clk->clk_id];581 const char *parents[CLK_SRC_MAX];582 583 clk->pll.reg = base;584 clk->mux.reg = base + clk->reg_offset + LPC18XX_CGU_PLL_CTRL_OFFSET;585 clk->gate.reg = base + clk->reg_offset + LPC18XX_CGU_PLL_CTRL_OFFSET;586 587 lpc18xx_fill_parent_names(parents, clk->mux.table, clk->n_parents);588 589 return clk_register_composite(NULL, name, parents, clk->n_parents,590 &clk->mux.hw, &clk_mux_ops,591 &clk->pll.hw, clk->pll_ops,592 &clk->gate.hw, &lpc18xx_gate_ops, 0);593}594 595static void __init lpc18xx_cgu_register_source_clks(struct device_node *np,596 void __iomem *base)597{598 const char *parents[CLK_SRC_MAX];599 struct clk *clk;600 int i;601 602 /* Register the internal 12 MHz RC oscillator (IRC) */603 clk = clk_register_fixed_rate(NULL, clk_src_names[CLK_SRC_IRC],604 NULL, 0, 12000000);605 if (IS_ERR(clk))606 pr_warn("%s: failed to register irc clk\n", __func__);607 608 /* Register crystal oscillator controller */609 parents[0] = of_clk_get_parent_name(np, 0);610 clk = clk_register_gate(NULL, clk_src_names[CLK_SRC_OSC], parents[0],611 0, base + LPC18XX_CGU_XTAL_OSC_CTRL,612 0, CLK_GATE_SET_TO_DISABLE, NULL);613 if (IS_ERR(clk))614 pr_warn("%s: failed to register osc clk\n", __func__);615 616 /* Register all PLLs */617 for (i = 0; i < ARRAY_SIZE(lpc18xx_cgu_src_clk_plls); i++) {618 clk = lpc18xx_cgu_register_pll(&lpc18xx_cgu_src_clk_plls[i],619 base);620 if (IS_ERR(clk))621 pr_warn("%s: failed to register pll (%d)\n", __func__, i);622 }623 624 /* Register all clock dividers A-E */625 for (i = 0; i < ARRAY_SIZE(lpc18xx_cgu_src_clk_divs); i++) {626 clk = lpc18xx_cgu_register_div(&lpc18xx_cgu_src_clk_divs[i],627 base, i);628 if (IS_ERR(clk))629 pr_warn("%s: failed to register div %d\n", __func__, i);630 }631}632 633static struct clk *clk_base[BASE_CLK_MAX];634static struct clk_onecell_data clk_base_data = {635 .clks = clk_base,636 .clk_num = BASE_CLK_MAX,637};638 639static void __init lpc18xx_cgu_register_base_clks(void __iomem *reg_base)640{641 int i;642 643 for (i = BASE_SAFE_CLK; i < BASE_CLK_MAX; i++) {644 clk_base[i] = lpc18xx_register_base_clk(&lpc18xx_cgu_base_clks[i],645 reg_base, i);646 if (IS_ERR(clk_base[i]) && PTR_ERR(clk_base[i]) != -ENOENT)647 pr_warn("%s: register base clk %d failed\n", __func__, i);648 }649}650 651static void __init lpc18xx_cgu_init(struct device_node *np)652{653 void __iomem *reg_base;654 655 reg_base = of_iomap(np, 0);656 if (!reg_base) {657 pr_warn("%s: failed to map address range\n", __func__);658 return;659 }660 661 lpc18xx_cgu_register_source_clks(np, reg_base);662 lpc18xx_cgu_register_base_clks(reg_base);663 664 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_base_data);665}666CLK_OF_DECLARE(lpc18xx_cgu, "nxp,lpc1850-cgu", lpc18xx_cgu_init);667