1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2014 Samsung Electronics Co., Ltd. 4 * Author: Thomas Abraham <thomas.ab@samsung.com> 5 * 6 * Copyright (c) 2015 Samsung Electronics Co., Ltd. 7 * Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> 8 * 9 * This file contains the utility function to register CPU clock for Samsung 10 * Exynos platforms. A CPU clock is defined as a clock supplied to a CPU or a 11 * group of CPUs. The CPU clock is typically derived from a hierarchy of clock 12 * blocks which includes mux and divider blocks. There are a number of other 13 * auxiliary clocks supplied to the CPU domain such as the debug blocks and AXI 14 * clock for CPU domain. The rates of these auxiliary clocks are related to the 15 * CPU clock rate and this relation is usually specified in the hardware manual 16 * of the SoC or supplied after the SoC characterization. 17 * 18 * The below implementation of the CPU clock allows the rate changes of the CPU 19 * clock and the corresponding rate changes of the auxiliary clocks of the CPU 20 * domain. The platform clock driver provides a clock register configuration 21 * for each configurable rate which is then used to program the clock hardware 22 * registers to achieve a fast coordinated rate change for all the CPU domain 23 * clocks. 24 * 25 * On a rate change request for the CPU clock, the rate change is propagated 26 * up to the PLL supplying the clock to the CPU domain clock blocks. While the 27 * CPU domain PLL is reconfigured, the CPU domain clocks are driven using an 28 * alternate clock source. If required, the alternate clock source is divided 29 * down in order to keep the output clock rate within the previous OPP limits. 30 */ 31 32 #include <linux/delay.h> 33 #include <linux/errno.h> 34 #include <linux/io.h> 35 #include <linux/slab.h> 36 #include <linux/clk.h> 37 #include <linux/clk-provider.h> 38 39 #include "clk.h" 40 #include "clk-cpu.h" 41 42 struct exynos_cpuclk; 43 44 typedef int (*exynos_rate_change_fn_t)(struct clk_notifier_data *ndata, 45 struct exynos_cpuclk *cpuclk); 46 47 /** 48 * struct exynos_cpuclk_regs - Register offsets for CPU related clocks 49 * @mux_sel: offset of CPU MUX_SEL register (for selecting MUX clock parent) 50 * @mux_stat: offset of CPU MUX_STAT register (for checking MUX clock status) 51 * @div_cpu0: offset of CPU DIV0 register (for modifying divider values) 52 * @div_cpu1: offset of CPU DIV1 register (for modifying divider values) 53 * @div_stat_cpu0: offset of CPU DIV0_STAT register (for checking DIV status) 54 * @div_stat_cpu1: offset of CPU DIV1_STAT register (for checking DIV status) 55 * @mux: offset of MUX register for choosing CPU clock source 56 * @divs: offsets of DIV registers (ACLK, ATCLK, PCLKDBG and PERIPHCLK) 57 */ 58 struct exynos_cpuclk_regs { 59 u32 mux_sel; 60 u32 mux_stat; 61 u32 div_cpu0; 62 u32 div_cpu1; 63 u32 div_stat_cpu0; 64 u32 div_stat_cpu1; 65 66 u32 mux; 67 u32 divs[4]; 68 }; 69 70 /** 71 * struct exynos_cpuclk_chip - Chip specific data for CPU clock 72 * @regs: register offsets for CPU related clocks 73 * @pre_rate_cb: callback to run before CPU clock rate change 74 * @post_rate_cb: callback to run after CPU clock rate change 75 */ 76 struct exynos_cpuclk_chip { 77 const struct exynos_cpuclk_regs *regs; 78 exynos_rate_change_fn_t pre_rate_cb; 79 exynos_rate_change_fn_t post_rate_cb; 80 }; 81 82 /** 83 * struct exynos_cpuclk - information about clock supplied to a CPU core 84 * @hw: handle between CCF and CPU clock 85 * @alt_parent: alternate parent clock to use when switching the speed 86 * of the primary parent clock 87 * @base: start address of the CPU clock registers block 88 * @lock: cpu clock domain register access lock 89 * @cfg: cpu clock rate configuration data 90 * @num_cfgs: number of array elements in @cfg array 91 * @clk_nb: clock notifier registered for changes in clock speed of the 92 * primary parent clock 93 * @flags: configuration flags for the CPU clock 94 * @chip: chip-specific data for the CPU clock 95 * 96 * This structure holds information required for programming the CPU clock for 97 * various clock speeds. 98 */ 99 struct exynos_cpuclk { 100 struct clk_hw hw; 101 const struct clk_hw *alt_parent; 102 void __iomem *base; 103 spinlock_t *lock; 104 const struct exynos_cpuclk_cfg_data *cfg; 105 const unsigned long num_cfgs; 106 struct notifier_block clk_nb; 107 unsigned long flags; 108 const struct exynos_cpuclk_chip *chip; 109 }; 110 111 /* ---- Common code --------------------------------------------------------- */ 112 113 /* Divider stabilization time, msec */ 114 #define MAX_STAB_TIME 10 115 #define MAX_DIV 8 116 #define DIV_MASK GENMASK(2, 0) 117 #define DIV_MASK_ALL GENMASK(31, 0) 118 #define MUX_MASK GENMASK(2, 0) 119 120 /* 121 * Helper function to wait until divider(s) have stabilized after the divider 122 * value has changed. 123 */ 124 static void wait_until_divider_stable(void __iomem *div_reg, unsigned long mask) 125 { 126 unsigned long timeout = jiffies + msecs_to_jiffies(MAX_STAB_TIME); 127 128 do { 129 if (!(readl(div_reg) & mask)) 130 return; 131 } while (time_before(jiffies, timeout)); 132 133 if (!(readl(div_reg) & mask)) 134 return; 135 136 pr_err("%s: timeout in divider stablization\n", __func__); 137 } 138 139 /* 140 * Helper function to wait until mux has stabilized after the mux selection 141 * value was changed. 142 */ 143 static void wait_until_mux_stable(void __iomem *mux_reg, u32 mux_pos, 144 unsigned long mask, unsigned long mux_value) 145 { 146 unsigned long timeout = jiffies + msecs_to_jiffies(MAX_STAB_TIME); 147 148 do { 149 if (((readl(mux_reg) >> mux_pos) & mask) == mux_value) 150 return; 151 } while (time_before(jiffies, timeout)); 152 153 if (((readl(mux_reg) >> mux_pos) & mask) == mux_value) 154 return; 155 156 pr_err("%s: re-parenting mux timed-out\n", __func__); 157 } 158 159 /* 160 * Helper function to set the 'safe' dividers for the CPU clock. The parameters 161 * div and mask contain the divider value and the register bit mask of the 162 * dividers to be programmed. 163 */ 164 static void exynos_set_safe_div(struct exynos_cpuclk *cpuclk, unsigned long div, 165 unsigned long mask) 166 { 167 const struct exynos_cpuclk_regs * const regs = cpuclk->chip->regs; 168 void __iomem *base = cpuclk->base; 169 unsigned long div0; 170 171 div0 = readl(base + regs->div_cpu0); 172 div0 = (div0 & ~mask) | (div & mask); 173 writel(div0, base + regs->div_cpu0); 174 wait_until_divider_stable(base + regs->div_stat_cpu0, mask); 175 } 176 177 /* ---- Exynos 3/4/5 -------------------------------------------------------- */ 178 179 #define E4210_DIV0_RATIO0_MASK GENMASK(2, 0) 180 #define E4210_DIV1_HPM_MASK GENMASK(6, 4) 181 #define E4210_DIV1_COPY_MASK GENMASK(2, 0) 182 #define E4210_MUX_HPM_MASK BIT(20) 183 #define E4210_DIV0_ATB_SHIFT 16 184 #define E4210_DIV0_ATB_MASK (DIV_MASK << E4210_DIV0_ATB_SHIFT) 185 186 static const struct exynos_cpuclk_regs e4210_cpuclk_regs = { 187 .mux_sel = 0x200, 188 .mux_stat = 0x400, 189 .div_cpu0 = 0x500, 190 .div_cpu1 = 0x504, 191 .div_stat_cpu0 = 0x600, 192 .div_stat_cpu1 = 0x604, 193 }; 194 195 /* handler for pre-rate change notification from parent clock */ 196 static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata, 197 struct exynos_cpuclk *cpuclk) 198 { 199 const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg; 200 const struct exynos_cpuclk_regs * const regs = cpuclk->chip->regs; 201 void __iomem *base = cpuclk->base; 202 unsigned long alt_prate = clk_hw_get_rate(cpuclk->alt_parent); 203 unsigned long div0, div1 = 0, mux_reg; 204 unsigned long flags; 205 206 /* find out the divider values to use for clock data */ 207 while ((cfg_data->prate * 1000) != ndata->new_rate) { 208 if (cfg_data->prate == 0) 209 return -EINVAL; 210 cfg_data++; 211 } 212 213 spin_lock_irqsave(cpuclk->lock, flags); 214 215 /* 216 * For the selected PLL clock frequency, get the pre-defined divider 217 * values. If the clock for sclk_hpm is not sourced from apll, then 218 * the values for DIV_COPY and DIV_HPM dividers need not be set. 219 */ 220 div0 = cfg_data->div0; 221 if (cpuclk->flags & CLK_CPU_HAS_DIV1) { 222 div1 = cfg_data->div1; 223 if (readl(base + regs->mux_sel) & E4210_MUX_HPM_MASK) 224 div1 = readl(base + regs->div_cpu1) & 225 (E4210_DIV1_HPM_MASK | E4210_DIV1_COPY_MASK); 226 } 227 228 /* 229 * If the old parent clock speed is less than the clock speed of 230 * the alternate parent, then it should be ensured that at no point 231 * the armclk speed is more than the old_prate until the dividers are 232 * set. Also workaround the issue of the dividers being set to lower 233 * values before the parent clock speed is set to new lower speed 234 * (this can result in too high speed of armclk output clocks). 235 */ 236 if (alt_prate > ndata->old_rate || ndata->old_rate > ndata->new_rate) { 237 unsigned long tmp_rate = min(ndata->old_rate, ndata->new_rate); 238 unsigned long alt_div, alt_div_mask = DIV_MASK; 239 240 alt_div = DIV_ROUND_UP(alt_prate, tmp_rate) - 1; 241 WARN_ON(alt_div >= MAX_DIV); 242 243 if (cpuclk->flags & CLK_CPU_NEEDS_DEBUG_ALT_DIV) { 244 /* 245 * In Exynos4210, ATB clock parent is also mout_core. So 246 * ATB clock also needs to be mantained at safe speed. 247 */ 248 alt_div |= E4210_DIV0_ATB_MASK; 249 alt_div_mask |= E4210_DIV0_ATB_MASK; 250 } 251 exynos_set_safe_div(cpuclk, alt_div, alt_div_mask); 252 div0 |= alt_div; 253 } 254 255 /* select sclk_mpll as the alternate parent */ 256 mux_reg = readl(base + regs->mux_sel); 257 writel(mux_reg | (1 << 16), base + regs->mux_sel); 258 wait_until_mux_stable(base + regs->mux_stat, 16, MUX_MASK, 2); 259 260 /* alternate parent is active now. set the dividers */ 261 writel(div0, base + regs->div_cpu0); 262 wait_until_divider_stable(base + regs->div_stat_cpu0, DIV_MASK_ALL); 263 264 if (cpuclk->flags & CLK_CPU_HAS_DIV1) { 265 writel(div1, base + regs->div_cpu1); 266 wait_until_divider_stable(base + regs->div_stat_cpu1, 267 DIV_MASK_ALL); 268 } 269 270 spin_unlock_irqrestore(cpuclk->lock, flags); 271 return 0; 272 } 273 274 /* handler for post-rate change notification from parent clock */ 275 static int exynos_cpuclk_post_rate_change(struct clk_notifier_data *ndata, 276 struct exynos_cpuclk *cpuclk) 277 { 278 const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg; 279 const struct exynos_cpuclk_regs * const regs = cpuclk->chip->regs; 280 void __iomem *base = cpuclk->base; 281 unsigned long div = 0, div_mask = DIV_MASK; 282 unsigned long mux_reg; 283 unsigned long flags; 284 285 /* find out the divider values to use for clock data */ 286 if (cpuclk->flags & CLK_CPU_NEEDS_DEBUG_ALT_DIV) { 287 while ((cfg_data->prate * 1000) != ndata->new_rate) { 288 if (cfg_data->prate == 0) 289 return -EINVAL; 290 cfg_data++; 291 } 292 } 293 294 spin_lock_irqsave(cpuclk->lock, flags); 295 296 /* select mout_apll as the alternate parent */ 297 mux_reg = readl(base + regs->mux_sel); 298 writel(mux_reg & ~(1 << 16), base + regs->mux_sel); 299 wait_until_mux_stable(base + regs->mux_stat, 16, MUX_MASK, 1); 300 301 if (cpuclk->flags & CLK_CPU_NEEDS_DEBUG_ALT_DIV) { 302 div |= (cfg_data->div0 & E4210_DIV0_ATB_MASK); 303 div_mask |= E4210_DIV0_ATB_MASK; 304 } 305 306 exynos_set_safe_div(cpuclk, div, div_mask); 307 spin_unlock_irqrestore(cpuclk->lock, flags); 308 return 0; 309 } 310 311 /* ---- Exynos5433 ---------------------------------------------------------- */ 312 313 static const struct exynos_cpuclk_regs e5433_cpuclk_regs = { 314 .mux_sel = 0x208, 315 .mux_stat = 0x408, 316 .div_cpu0 = 0x600, 317 .div_cpu1 = 0x604, 318 .div_stat_cpu0 = 0x700, 319 .div_stat_cpu1 = 0x704, 320 }; 321 322 /* handler for pre-rate change notification from parent clock */ 323 static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata, 324 struct exynos_cpuclk *cpuclk) 325 { 326 const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg; 327 const struct exynos_cpuclk_regs * const regs = cpuclk->chip->regs; 328 void __iomem *base = cpuclk->base; 329 unsigned long alt_prate = clk_hw_get_rate(cpuclk->alt_parent); 330 unsigned long div0, div1 = 0, mux_reg; 331 unsigned long flags; 332 333 /* find out the divider values to use for clock data */ 334 while ((cfg_data->prate * 1000) != ndata->new_rate) { 335 if (cfg_data->prate == 0) 336 return -EINVAL; 337 cfg_data++; 338 } 339 340 spin_lock_irqsave(cpuclk->lock, flags); 341 342 /* 343 * For the selected PLL clock frequency, get the pre-defined divider 344 * values. 345 */ 346 div0 = cfg_data->div0; 347 div1 = cfg_data->div1; 348 349 /* 350 * If the old parent clock speed is less than the clock speed of 351 * the alternate parent, then it should be ensured that at no point 352 * the armclk speed is more than the old_prate until the dividers are 353 * set. Also workaround the issue of the dividers being set to lower 354 * values before the parent clock speed is set to new lower speed 355 * (this can result in too high speed of armclk output clocks). 356 */ 357 if (alt_prate > ndata->old_rate || ndata->old_rate > ndata->new_rate) { 358 unsigned long tmp_rate = min(ndata->old_rate, ndata->new_rate); 359 unsigned long alt_div, alt_div_mask = DIV_MASK; 360 361 alt_div = DIV_ROUND_UP(alt_prate, tmp_rate) - 1; 362 WARN_ON(alt_div >= MAX_DIV); 363 364 exynos_set_safe_div(cpuclk, alt_div, alt_div_mask); 365 div0 |= alt_div; 366 } 367 368 /* select the alternate parent */ 369 mux_reg = readl(base + regs->mux_sel); 370 writel(mux_reg | 1, base + regs->mux_sel); 371 wait_until_mux_stable(base + regs->mux_stat, 0, MUX_MASK, 2); 372 373 /* alternate parent is active now. set the dividers */ 374 writel(div0, base + regs->div_cpu0); 375 wait_until_divider_stable(base + regs->div_stat_cpu0, DIV_MASK_ALL); 376 377 writel(div1, base + regs->div_cpu1); 378 wait_until_divider_stable(base + regs->div_stat_cpu1, DIV_MASK_ALL); 379 380 spin_unlock_irqrestore(cpuclk->lock, flags); 381 return 0; 382 } 383 384 /* handler for post-rate change notification from parent clock */ 385 static int exynos5433_cpuclk_post_rate_change(struct clk_notifier_data *ndata, 386 struct exynos_cpuclk *cpuclk) 387 { 388 const struct exynos_cpuclk_regs * const regs = cpuclk->chip->regs; 389 void __iomem *base = cpuclk->base; 390 unsigned long div = 0, div_mask = DIV_MASK; 391 unsigned long mux_reg; 392 unsigned long flags; 393 394 spin_lock_irqsave(cpuclk->lock, flags); 395 396 /* select apll as the alternate parent */ 397 mux_reg = readl(base + regs->mux_sel); 398 writel(mux_reg & ~1, base + regs->mux_sel); 399 wait_until_mux_stable(base + regs->mux_stat, 0, MUX_MASK, 1); 400 401 exynos_set_safe_div(cpuclk, div, div_mask); 402 spin_unlock_irqrestore(cpuclk->lock, flags); 403 return 0; 404 } 405 406 /* ---- Exynos850 ----------------------------------------------------------- */ 407 408 #define E850_DIV_RATIO_MASK GENMASK(3, 0) 409 #define E850_BUSY_MASK BIT(16) 410 411 /* Max time for divider or mux to stabilize, usec */ 412 #define E850_DIV_MUX_STAB_TIME 100 413 /* OSCCLK clock rate, Hz */ 414 #define E850_OSCCLK (26 * MHZ) 415 416 static const struct exynos_cpuclk_regs e850cl0_cpuclk_regs = { 417 .mux = 0x100c, 418 .divs = { 0x1800, 0x1808, 0x180c, 0x1810 }, 419 }; 420 421 static const struct exynos_cpuclk_regs e850cl1_cpuclk_regs = { 422 .mux = 0x1000, 423 .divs = { 0x1800, 0x1808, 0x180c, 0x1810 }, 424 }; 425 426 /* 427 * Set alternate parent rate to "rate" value or less. 428 * 429 * rate: Desired alt_parent rate, or 0 for max alt_parent rate 430 * 431 * Exynos850 doesn't have CPU clock divider in CMU_CPUCLx block (CMUREF divider 432 * doesn't affect CPU speed). So CPUCLx_SWITCH divider from CMU_TOP is used 433 * instead to adjust alternate parent speed. 434 * 435 * It's possible to use clk_set_max_rate() instead of this function, but it 436 * would set overly pessimistic rate values to alternate parent. 437 */ 438 static int exynos850_alt_parent_set_max_rate(const struct clk_hw *alt_parent, 439 unsigned long rate) 440 { 441 struct clk_hw *clk_div, *clk_divp; 442 unsigned long divp_rate, div_rate, div; 443 int ret; 444 445 /* Divider from CMU_TOP */ 446 clk_div = clk_hw_get_parent(alt_parent); 447 if (!clk_div) 448 return -ENOENT; 449 /* Divider's parent from CMU_TOP */ 450 clk_divp = clk_hw_get_parent(clk_div); 451 if (!clk_divp) 452 return -ENOENT; 453 /* Divider input rate */ 454 divp_rate = clk_hw_get_rate(clk_divp); 455 if (!divp_rate) 456 return -EINVAL; 457 458 /* Calculate new alt_parent rate for integer divider value */ 459 if (rate == 0) 460 div = 1; 461 else 462 div = DIV_ROUND_UP(divp_rate, rate); 463 div_rate = DIV_ROUND_UP(divp_rate, div); 464 WARN_ON(div >= MAX_DIV); 465 466 /* alt_parent will propagate this change up to the divider */ 467 ret = clk_set_rate(alt_parent->clk, div_rate); 468 if (ret) 469 return ret; 470 udelay(E850_DIV_MUX_STAB_TIME); 471 472 return 0; 473 } 474 475 /* Handler for pre-rate change notification from parent clock */ 476 static int exynos850_cpuclk_pre_rate_change(struct clk_notifier_data *ndata, 477 struct exynos_cpuclk *cpuclk) 478 { 479 const unsigned int shifts[4] = { 16, 12, 8, 4 }; /* E850_CPU_DIV0() */ 480 const struct exynos_cpuclk_regs * const regs = cpuclk->chip->regs; 481 const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg; 482 const struct clk_hw *alt_parent = cpuclk->alt_parent; 483 void __iomem *base = cpuclk->base; 484 unsigned long alt_prate = clk_hw_get_rate(alt_parent); 485 unsigned long flags; 486 u32 mux_reg; 487 size_t i; 488 int ret; 489 490 /* No actions are needed when switching to or from OSCCLK parent */ 491 if (ndata->new_rate == E850_OSCCLK || ndata->old_rate == E850_OSCCLK) 492 return 0; 493 494 /* Find out the divider values to use for clock data */ 495 while ((cfg_data->prate * 1000) != ndata->new_rate) { 496 if (cfg_data->prate == 0) 497 return -EINVAL; 498 cfg_data++; 499 } 500 501 /* 502 * If the old parent clock speed is less than the clock speed of 503 * the alternate parent, then it should be ensured that at no point 504 * the armclk speed is more than the old_prate until the dividers are 505 * set. Also workaround the issue of the dividers being set to lower 506 * values before the parent clock speed is set to new lower speed 507 * (this can result in too high speed of armclk output clocks). 508 */ 509 if (alt_prate > ndata->old_rate || ndata->old_rate > ndata->new_rate) { 510 unsigned long tmp_rate = min(ndata->old_rate, ndata->new_rate); 511 512 ret = exynos850_alt_parent_set_max_rate(alt_parent, tmp_rate); 513 if (ret) 514 return ret; 515 } 516 517 spin_lock_irqsave(cpuclk->lock, flags); 518 519 /* Select the alternate parent */ 520 mux_reg = readl(base + regs->mux); 521 writel(mux_reg | 1, base + regs->mux); 522 wait_until_mux_stable(base + regs->mux, 16, 1, 0); 523 524 /* Alternate parent is active now. Set the dividers */ 525 for (i = 0; i < ARRAY_SIZE(shifts); ++i) { 526 unsigned long div = (cfg_data->div0 >> shifts[i]) & 0xf; 527 u32 val; 528 529 val = readl(base + regs->divs[i]); 530 val = (val & ~E850_DIV_RATIO_MASK) | div; 531 writel(val, base + regs->divs[i]); 532 wait_until_divider_stable(base + regs->divs[i], E850_BUSY_MASK); 533 } 534 535 spin_unlock_irqrestore(cpuclk->lock, flags); 536 537 return 0; 538 } 539 540 /* Handler for post-rate change notification from parent clock */ 541 static int exynos850_cpuclk_post_rate_change(struct clk_notifier_data *ndata, 542 struct exynos_cpuclk *cpuclk) 543 { 544 const struct exynos_cpuclk_regs * const regs = cpuclk->chip->regs; 545 const struct clk_hw *alt_parent = cpuclk->alt_parent; 546 void __iomem *base = cpuclk->base; 547 unsigned long flags; 548 u32 mux_reg; 549 550 /* No actions are needed when switching to or from OSCCLK parent */ 551 if (ndata->new_rate == E850_OSCCLK || ndata->old_rate == E850_OSCCLK) 552 return 0; 553 554 spin_lock_irqsave(cpuclk->lock, flags); 555 556 /* Select main parent (PLL) for mux */ 557 mux_reg = readl(base + regs->mux); 558 writel(mux_reg & ~1, base + regs->mux); 559 wait_until_mux_stable(base + regs->mux, 16, 1, 0); 560 561 spin_unlock_irqrestore(cpuclk->lock, flags); 562 563 /* Set alt_parent rate back to max */ 564 return exynos850_alt_parent_set_max_rate(alt_parent, 0); 565 } 566 567 /* -------------------------------------------------------------------------- */ 568 569 /* Common round rate callback usable for all types of CPU clocks */ 570 static long exynos_cpuclk_round_rate(struct clk_hw *hw, unsigned long drate, 571 unsigned long *prate) 572 { 573 struct clk_hw *parent = clk_hw_get_parent(hw); 574 *prate = clk_hw_round_rate(parent, drate); 575 return *prate; 576 } 577 578 /* Common recalc rate callback usable for all types of CPU clocks */ 579 static unsigned long exynos_cpuclk_recalc_rate(struct clk_hw *hw, 580 unsigned long parent_rate) 581 { 582 /* 583 * The CPU clock output (armclk) rate is the same as its parent 584 * rate. Although there exist certain dividers inside the CPU 585 * clock block that could be used to divide the parent clock, 586 * the driver does not make use of them currently, except during 587 * frequency transitions. 588 */ 589 return parent_rate; 590 } 591 592 static const struct clk_ops exynos_cpuclk_clk_ops = { 593 .recalc_rate = exynos_cpuclk_recalc_rate, 594 .round_rate = exynos_cpuclk_round_rate, 595 }; 596 597 /* 598 * This notifier function is called for the pre-rate and post-rate change 599 * notifications of the parent clock of cpuclk. 600 */ 601 static int exynos_cpuclk_notifier_cb(struct notifier_block *nb, 602 unsigned long event, void *data) 603 { 604 struct clk_notifier_data *ndata = data; 605 struct exynos_cpuclk *cpuclk; 606 int err = 0; 607 608 cpuclk = container_of(nb, struct exynos_cpuclk, clk_nb); 609 610 if (event == PRE_RATE_CHANGE) 611 err = cpuclk->chip->pre_rate_cb(ndata, cpuclk); 612 else if (event == POST_RATE_CHANGE) 613 err = cpuclk->chip->post_rate_cb(ndata, cpuclk); 614 615 return notifier_from_errno(err); 616 } 617 618 static const struct exynos_cpuclk_chip exynos_clkcpu_chips[] = { 619 [CPUCLK_LAYOUT_E4210] = { 620 .regs = &e4210_cpuclk_regs, 621 .pre_rate_cb = exynos_cpuclk_pre_rate_change, 622 .post_rate_cb = exynos_cpuclk_post_rate_change, 623 }, 624 [CPUCLK_LAYOUT_E5433] = { 625 .regs = &e5433_cpuclk_regs, 626 .pre_rate_cb = exynos5433_cpuclk_pre_rate_change, 627 .post_rate_cb = exynos5433_cpuclk_post_rate_change, 628 }, 629 [CPUCLK_LAYOUT_E850_CL0] = { 630 .regs = &e850cl0_cpuclk_regs, 631 .pre_rate_cb = exynos850_cpuclk_pre_rate_change, 632 .post_rate_cb = exynos850_cpuclk_post_rate_change, 633 }, 634 [CPUCLK_LAYOUT_E850_CL1] = { 635 .regs = &e850cl1_cpuclk_regs, 636 .pre_rate_cb = exynos850_cpuclk_pre_rate_change, 637 .post_rate_cb = exynos850_cpuclk_post_rate_change, 638 }, 639 }; 640 641 /* helper function to register a CPU clock */ 642 static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx, 643 const struct samsung_cpu_clock *clk_data) 644 { 645 const struct clk_hw *parent, *alt_parent; 646 struct clk_hw **hws; 647 struct exynos_cpuclk *cpuclk; 648 struct clk_init_data init; 649 const char *parent_name; 650 unsigned int num_cfgs; 651 int ret = 0; 652 653 hws = ctx->clk_data.hws; 654 parent = hws[clk_data->parent_id]; 655 alt_parent = hws[clk_data->alt_parent_id]; 656 if (IS_ERR(parent) || IS_ERR(alt_parent)) { 657 pr_err("%s: invalid parent clock(s)\n", __func__); 658 return -EINVAL; 659 } 660 661 cpuclk = kzalloc(sizeof(*cpuclk), GFP_KERNEL); 662 if (!cpuclk) 663 return -ENOMEM; 664 665 parent_name = clk_hw_get_name(parent); 666 667 init.name = clk_data->name; 668 init.flags = CLK_SET_RATE_PARENT; 669 init.parent_names = &parent_name; 670 init.num_parents = 1; 671 init.ops = &exynos_cpuclk_clk_ops; 672 673 cpuclk->alt_parent = alt_parent; 674 cpuclk->hw.init = &init; 675 cpuclk->base = ctx->reg_base + clk_data->offset; 676 cpuclk->lock = &ctx->lock; 677 cpuclk->flags = clk_data->flags; 678 cpuclk->clk_nb.notifier_call = exynos_cpuclk_notifier_cb; 679 cpuclk->chip = &exynos_clkcpu_chips[clk_data->reg_layout]; 680 681 ret = clk_notifier_register(parent->clk, &cpuclk->clk_nb); 682 if (ret) { 683 pr_err("%s: failed to register clock notifier for %s\n", 684 __func__, clk_data->name); 685 goto free_cpuclk; 686 } 687 688 /* Find count of configuration rates in cfg */ 689 for (num_cfgs = 0; clk_data->cfg[num_cfgs].prate != 0; ) 690 num_cfgs++; 691 692 cpuclk->cfg = kmemdup(clk_data->cfg, sizeof(*clk_data->cfg) * num_cfgs, 693 GFP_KERNEL); 694 if (!cpuclk->cfg) { 695 ret = -ENOMEM; 696 goto unregister_clk_nb; 697 } 698 699 ret = clk_hw_register(NULL, &cpuclk->hw); 700 if (ret) { 701 pr_err("%s: could not register cpuclk %s\n", __func__, 702 clk_data->name); 703 goto free_cpuclk_data; 704 } 705 706 samsung_clk_add_lookup(ctx, &cpuclk->hw, clk_data->id); 707 return 0; 708 709 free_cpuclk_data: 710 kfree(cpuclk->cfg); 711 unregister_clk_nb: 712 clk_notifier_unregister(parent->clk, &cpuclk->clk_nb); 713 free_cpuclk: 714 kfree(cpuclk); 715 return ret; 716 } 717 718 void __init samsung_clk_register_cpu(struct samsung_clk_provider *ctx, 719 const struct samsung_cpu_clock *list, unsigned int nr_clk) 720 { 721 unsigned int idx; 722 723 for (idx = 0; idx < nr_clk; idx++) 724 exynos_register_cpu_clock(ctx, &list[idx]); 725 } 726