1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2013 Samsung Electronics Co., Ltd. 4 * Copyright (c) 2013 Linaro Ltd. 5 * Author: Thomas Abraham <thomas.ab@samsung.com> 6 * 7 * This file includes utility functions to register clocks to common 8 * clock framework for Samsung platforms. 9 */ 10 11 #include <linux/slab.h> 12 #include <linux/clkdev.h> 13 #include <linux/clk-provider.h> 14 #include <linux/io.h> 15 #include <linux/mfd/syscon.h> 16 #include <linux/mod_devicetable.h> 17 #include <linux/of_address.h> 18 #include <linux/regmap.h> 19 #include <linux/syscore_ops.h> 20 21 #include "clk.h" 22 23 static LIST_HEAD(clock_reg_cache_list); 24 25 void samsung_clk_save(void __iomem *base, 26 struct regmap *regmap, 27 struct samsung_clk_reg_dump *rd, 28 unsigned int num_regs) 29 { 30 for (; num_regs > 0; --num_regs, ++rd) { 31 if (base) 32 rd->value = readl(base + rd->offset); 33 else if (regmap) 34 regmap_read(regmap, rd->offset, &rd->value); 35 } 36 } 37 38 void samsung_clk_restore(void __iomem *base, 39 struct regmap *regmap, 40 const struct samsung_clk_reg_dump *rd, 41 unsigned int num_regs) 42 { 43 for (; num_regs > 0; --num_regs, ++rd) { 44 if (base) 45 writel(rd->value, base + rd->offset); 46 else if (regmap) 47 regmap_write(regmap, rd->offset, rd->value); 48 } 49 } 50 51 struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump( 52 const unsigned long *rdump, 53 unsigned long nr_rdump) 54 { 55 struct samsung_clk_reg_dump *rd; 56 unsigned int i; 57 58 rd = kzalloc_objs(*rd, nr_rdump); 59 if (!rd) 60 return NULL; 61 62 for (i = 0; i < nr_rdump; ++i) 63 rd[i].offset = rdump[i]; 64 65 return rd; 66 } 67 68 /** 69 * samsung_clk_init() - Create and initialize a clock provider object 70 * @dev: CMU device to enable runtime PM, or NULL if RPM is not needed 71 * @base: Start address (mapped) of CMU registers 72 * @nr_clks: Total clock count to allocate in clock provider object 73 * 74 * Setup the essentials required to support clock lookup using Common Clock 75 * Framework. 76 * 77 * Return: Allocated and initialized clock provider object. 78 */ 79 struct samsung_clk_provider * __init samsung_clk_init(struct device *dev, 80 void __iomem *base, unsigned long nr_clks) 81 { 82 struct samsung_clk_provider *ctx; 83 int i; 84 85 ctx = kzalloc_flex(*ctx, clk_data.hws, nr_clks); 86 if (!ctx) 87 panic("could not allocate clock provider context.\n"); 88 89 ctx->clk_data.num = nr_clks; 90 for (i = 0; i < nr_clks; ++i) 91 ctx->clk_data.hws[i] = ERR_PTR(-ENOENT); 92 93 ctx->dev = dev; 94 ctx->reg_base = base; 95 spin_lock_init(&ctx->lock); 96 97 return ctx; 98 } 99 100 void __init samsung_clk_of_add_provider(struct device_node *np, 101 struct samsung_clk_provider *ctx) 102 { 103 if (np) { 104 if (of_clk_add_hw_provider(np, of_clk_hw_onecell_get, 105 &ctx->clk_data)) 106 panic("could not register clk provider\n"); 107 } 108 } 109 110 /* add a clock instance to the clock lookup table used for dt based lookup */ 111 void samsung_clk_add_lookup(struct samsung_clk_provider *ctx, 112 struct clk_hw *clk_hw, unsigned int id) 113 { 114 if (id) 115 ctx->clk_data.hws[id] = clk_hw; 116 } 117 118 /* register a list of aliases */ 119 void __init samsung_clk_register_alias(struct samsung_clk_provider *ctx, 120 const struct samsung_clock_alias *list, 121 unsigned int nr_clk) 122 { 123 struct clk_hw *clk_hw; 124 unsigned int idx, ret; 125 126 for (idx = 0; idx < nr_clk; idx++, list++) { 127 if (!list->id) { 128 pr_err("%s: clock id missing for index %d\n", __func__, 129 idx); 130 continue; 131 } 132 133 clk_hw = ctx->clk_data.hws[list->id]; 134 if (!clk_hw) { 135 pr_err("%s: failed to find clock %d\n", __func__, 136 list->id); 137 continue; 138 } 139 140 ret = clk_hw_register_clkdev(clk_hw, list->alias, 141 list->dev_name); 142 if (ret) 143 pr_err("%s: failed to register lookup %s\n", 144 __func__, list->alias); 145 } 146 } 147 148 /* register a list of fixed clocks */ 149 void __init samsung_clk_register_fixed_rate(struct samsung_clk_provider *ctx, 150 const struct samsung_fixed_rate_clock *list, 151 unsigned int nr_clk) 152 { 153 struct clk_hw *clk_hw; 154 unsigned int idx; 155 156 for (idx = 0; idx < nr_clk; idx++, list++) { 157 clk_hw = clk_hw_register_fixed_rate(ctx->dev, list->name, 158 list->parent_name, list->flags, list->fixed_rate); 159 if (IS_ERR(clk_hw)) { 160 pr_err("%s: failed to register clock %s\n", __func__, 161 list->name); 162 continue; 163 } 164 165 samsung_clk_add_lookup(ctx, clk_hw, list->id); 166 } 167 } 168 169 /* register a list of fixed factor clocks */ 170 void __init samsung_clk_register_fixed_factor(struct samsung_clk_provider *ctx, 171 const struct samsung_fixed_factor_clock *list, unsigned int nr_clk) 172 { 173 struct clk_hw *clk_hw; 174 unsigned int idx; 175 176 for (idx = 0; idx < nr_clk; idx++, list++) { 177 clk_hw = clk_hw_register_fixed_factor(ctx->dev, list->name, 178 list->parent_name, list->flags, list->mult, list->div); 179 if (IS_ERR(clk_hw)) { 180 pr_err("%s: failed to register clock %s\n", __func__, 181 list->name); 182 continue; 183 } 184 185 samsung_clk_add_lookup(ctx, clk_hw, list->id); 186 } 187 } 188 189 /* register a list of mux clocks */ 190 void __init samsung_clk_register_mux(struct samsung_clk_provider *ctx, 191 const struct samsung_mux_clock *list, 192 unsigned int nr_clk) 193 { 194 struct clk_hw *clk_hw; 195 unsigned int idx; 196 197 for (idx = 0; idx < nr_clk; idx++, list++) { 198 clk_hw = clk_hw_register_mux(ctx->dev, list->name, 199 list->parent_names, list->num_parents, list->flags, 200 ctx->reg_base + list->offset, 201 list->shift, list->width, list->mux_flags, &ctx->lock); 202 if (IS_ERR(clk_hw)) { 203 pr_err("%s: failed to register clock %s\n", __func__, 204 list->name); 205 continue; 206 } 207 208 samsung_clk_add_lookup(ctx, clk_hw, list->id); 209 } 210 } 211 212 /* register a list of div clocks */ 213 void __init samsung_clk_register_div(struct samsung_clk_provider *ctx, 214 const struct samsung_div_clock *list, 215 unsigned int nr_clk) 216 { 217 struct clk_hw *clk_hw; 218 unsigned int idx; 219 220 for (idx = 0; idx < nr_clk; idx++, list++) { 221 if (list->table) 222 clk_hw = clk_hw_register_divider_table(ctx->dev, 223 list->name, list->parent_name, list->flags, 224 ctx->reg_base + list->offset, 225 list->shift, list->width, list->div_flags, 226 list->table, &ctx->lock); 227 else 228 clk_hw = clk_hw_register_divider(ctx->dev, list->name, 229 list->parent_name, list->flags, 230 ctx->reg_base + list->offset, list->shift, 231 list->width, list->div_flags, &ctx->lock); 232 if (IS_ERR(clk_hw)) { 233 pr_err("%s: failed to register clock %s\n", __func__, 234 list->name); 235 continue; 236 } 237 238 samsung_clk_add_lookup(ctx, clk_hw, list->id); 239 } 240 } 241 242 /* 243 * Some older DT's have an incorrect CMU resource size which is incompatible 244 * with the auto clock mode feature. In such cases we switch back to manual 245 * clock gating mode. 246 */ 247 bool samsung_is_auto_capable(struct device_node *np) 248 { 249 struct resource res; 250 resource_size_t size; 251 252 if (of_address_to_resource(np, 0, &res)) 253 return false; 254 255 size = resource_size(&res); 256 if (size != 0x10000) { 257 pr_warn("%pOF: incorrect res size for automatic clocks\n", np); 258 return false; 259 } 260 return true; 261 } 262 263 #define ACG_MSK GENMASK(6, 4) 264 #define CLK_IDLE GENMASK(5, 4) 265 static int samsung_auto_clk_gate_is_en(struct clk_hw *hw) 266 { 267 u32 reg; 268 struct clk_gate *gate = to_clk_gate(hw); 269 270 reg = readl(gate->reg); 271 return ((reg & ACG_MSK) == CLK_IDLE) ? 0 : 1; 272 } 273 274 /* enable and disable are nops in automatic clock mode */ 275 static int samsung_auto_clk_gate_en(struct clk_hw *hw) 276 { 277 return 0; 278 } 279 280 static void samsung_auto_clk_gate_dis(struct clk_hw *hw) 281 { 282 } 283 284 static const struct clk_ops samsung_auto_clk_gate_ops = { 285 .enable = samsung_auto_clk_gate_en, 286 .disable = samsung_auto_clk_gate_dis, 287 .is_enabled = samsung_auto_clk_gate_is_en, 288 }; 289 290 struct clk_hw *samsung_register_auto_gate(struct device *dev, 291 struct device_node *np, const char *name, 292 const char *parent_name, const struct clk_hw *parent_hw, 293 const struct clk_parent_data *parent_data, 294 unsigned long flags, 295 void __iomem *reg, u8 bit_idx, 296 u8 clk_gate_flags, spinlock_t *lock) 297 { 298 struct clk_gate *gate; 299 struct clk_hw *hw; 300 struct clk_init_data init = {}; 301 int ret = -EINVAL; 302 303 /* allocate the gate */ 304 gate = kzalloc_obj(*gate); 305 if (!gate) 306 return ERR_PTR(-ENOMEM); 307 308 init.name = name; 309 init.ops = &samsung_auto_clk_gate_ops; 310 init.flags = flags; 311 init.parent_names = parent_name ? &parent_name : NULL; 312 init.parent_hws = parent_hw ? &parent_hw : NULL; 313 init.parent_data = parent_data; 314 if (parent_name || parent_hw || parent_data) 315 init.num_parents = 1; 316 else 317 init.num_parents = 0; 318 319 /* struct clk_gate assignments */ 320 gate->reg = reg; 321 gate->bit_idx = bit_idx; 322 gate->flags = clk_gate_flags; 323 gate->lock = lock; 324 gate->hw.init = &init; 325 326 hw = &gate->hw; 327 if (dev || !np) 328 ret = clk_hw_register(dev, hw); 329 else if (np) 330 ret = of_clk_hw_register(np, hw); 331 if (ret) { 332 kfree(gate); 333 hw = ERR_PTR(ret); 334 } 335 336 return hw; 337 } 338 339 /* register a list of gate clocks */ 340 void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx, 341 const struct samsung_gate_clock *list, 342 unsigned int nr_clk) 343 { 344 struct clk_hw *clk_hw; 345 unsigned int idx; 346 void __iomem *reg_offs; 347 348 for (idx = 0; idx < nr_clk; idx++, list++) { 349 reg_offs = ctx->reg_base + list->offset; 350 351 if (ctx->auto_clock_gate && ctx->gate_dbg_offset) 352 clk_hw = samsung_register_auto_gate(ctx->dev, NULL, 353 list->name, list->parent_name, NULL, NULL, 354 list->flags, reg_offs + ctx->gate_dbg_offset, 355 list->bit_idx, list->gate_flags, &ctx->lock); 356 else 357 clk_hw = clk_hw_register_gate(ctx->dev, list->name, 358 list->parent_name, list->flags, 359 ctx->reg_base + list->offset, list->bit_idx, 360 list->gate_flags, &ctx->lock); 361 if (IS_ERR(clk_hw)) { 362 pr_err("%s: failed to register clock %s: %ld\n", __func__, 363 list->name, PTR_ERR(clk_hw)); 364 continue; 365 } 366 367 samsung_clk_add_lookup(ctx, clk_hw, list->id); 368 } 369 } 370 371 /* 372 * obtain the clock speed of all external fixed clock sources from device 373 * tree and register it 374 */ 375 void __init samsung_clk_of_register_fixed_ext(struct samsung_clk_provider *ctx, 376 struct samsung_fixed_rate_clock *fixed_rate_clk, 377 unsigned int nr_fixed_rate_clk, 378 const struct of_device_id *clk_matches) 379 { 380 const struct of_device_id *match; 381 struct device_node *clk_np; 382 u32 freq; 383 384 for_each_matching_node_and_match(clk_np, clk_matches, &match) { 385 if (of_property_read_u32(clk_np, "clock-frequency", &freq)) 386 continue; 387 fixed_rate_clk[(unsigned long)match->data].fixed_rate = freq; 388 } 389 samsung_clk_register_fixed_rate(ctx, fixed_rate_clk, nr_fixed_rate_clk); 390 } 391 392 #ifdef CONFIG_PM_SLEEP 393 static int samsung_clk_suspend(void *data) 394 { 395 struct samsung_clock_reg_cache *reg_cache; 396 397 list_for_each_entry(reg_cache, &clock_reg_cache_list, node) { 398 samsung_clk_save(reg_cache->reg_base, reg_cache->sysreg, 399 reg_cache->rdump, reg_cache->rd_num); 400 samsung_clk_restore(reg_cache->reg_base, reg_cache->sysreg, 401 reg_cache->rsuspend, 402 reg_cache->rsuspend_num); 403 } 404 return 0; 405 } 406 407 static void samsung_clk_resume(void *data) 408 { 409 struct samsung_clock_reg_cache *reg_cache; 410 411 list_for_each_entry(reg_cache, &clock_reg_cache_list, node) 412 samsung_clk_restore(reg_cache->reg_base, reg_cache->sysreg, 413 reg_cache->rdump, reg_cache->rd_num); 414 } 415 416 static const struct syscore_ops samsung_clk_syscore_ops = { 417 .suspend = samsung_clk_suspend, 418 .resume = samsung_clk_resume, 419 }; 420 421 static struct syscore samsung_clk_syscore = { 422 .ops = &samsung_clk_syscore_ops, 423 }; 424 425 void samsung_clk_extended_sleep_init(void __iomem *reg_base, 426 struct regmap *sysreg, 427 const unsigned long *rdump, 428 unsigned long nr_rdump, 429 const struct samsung_clk_reg_dump *rsuspend, 430 unsigned long nr_rsuspend) 431 { 432 struct samsung_clock_reg_cache *reg_cache; 433 434 reg_cache = kzalloc_obj(struct samsung_clock_reg_cache); 435 if (!reg_cache) 436 panic("could not allocate register reg_cache.\n"); 437 reg_cache->rdump = samsung_clk_alloc_reg_dump(rdump, nr_rdump); 438 439 if (!reg_cache->rdump) 440 panic("could not allocate register dump storage.\n"); 441 442 if (list_empty(&clock_reg_cache_list)) 443 register_syscore(&samsung_clk_syscore); 444 445 reg_cache->reg_base = reg_base; 446 reg_cache->sysreg = sysreg; 447 reg_cache->rd_num = nr_rdump; 448 reg_cache->rsuspend = rsuspend; 449 reg_cache->rsuspend_num = nr_rsuspend; 450 list_add_tail(®_cache->node, &clock_reg_cache_list); 451 } 452 #endif 453 454 /** 455 * samsung_cmu_register_clocks() - Register all clocks provided in CMU object 456 * @ctx: Clock provider object 457 * @cmu: CMU object with clocks to register 458 * @np: CMU device tree node 459 */ 460 void __init samsung_cmu_register_clocks(struct samsung_clk_provider *ctx, 461 const struct samsung_cmu_info *cmu, 462 struct device_node *np) 463 { 464 if (cmu->auto_clock_gate && samsung_is_auto_capable(np)) 465 ctx->auto_clock_gate = cmu->auto_clock_gate; 466 467 ctx->gate_dbg_offset = cmu->gate_dbg_offset; 468 ctx->option_offset = cmu->option_offset; 469 ctx->drcg_offset = cmu->drcg_offset; 470 ctx->memclk_offset = cmu->memclk_offset; 471 472 if (cmu->pll_clks) 473 samsung_clk_register_pll(ctx, cmu->pll_clks, cmu->nr_pll_clks); 474 if (cmu->mux_clks) 475 samsung_clk_register_mux(ctx, cmu->mux_clks, cmu->nr_mux_clks); 476 if (cmu->div_clks) 477 samsung_clk_register_div(ctx, cmu->div_clks, cmu->nr_div_clks); 478 if (cmu->gate_clks) 479 samsung_clk_register_gate(ctx, cmu->gate_clks, 480 cmu->nr_gate_clks); 481 if (cmu->fixed_clks) 482 samsung_clk_register_fixed_rate(ctx, cmu->fixed_clks, 483 cmu->nr_fixed_clks); 484 if (cmu->fixed_factor_clks) 485 samsung_clk_register_fixed_factor(ctx, cmu->fixed_factor_clks, 486 cmu->nr_fixed_factor_clks); 487 if (cmu->cpu_clks) 488 samsung_clk_register_cpu(ctx, cmu->cpu_clks, cmu->nr_cpu_clks); 489 } 490 491 /* Each bit enable/disables DRCG of a bus component */ 492 #define DRCG_EN_MSK GENMASK(31, 0) 493 #define MEMCLK_EN BIT(0) 494 495 /* Enable Dynamic Root Clock Gating (DRCG) of bus components */ 496 void samsung_en_dyn_root_clk_gating(struct device_node *np, 497 struct samsung_clk_provider *ctx, 498 const struct samsung_cmu_info *cmu, 499 bool cmu_has_pm) 500 { 501 if (!ctx->auto_clock_gate) 502 return; 503 504 ctx->sysreg = syscon_regmap_lookup_by_phandle(np, "samsung,sysreg"); 505 if (IS_ERR(ctx->sysreg)) { 506 pr_warn("%pOF: Unable to get CMU sysreg\n", np); 507 ctx->sysreg = NULL; 508 } else { 509 /* Enable DRCG for all bus components */ 510 regmap_write(ctx->sysreg, ctx->drcg_offset, DRCG_EN_MSK); 511 /* Enable memclk gate (not present on all sysreg) */ 512 if (ctx->memclk_offset) 513 regmap_write_bits(ctx->sysreg, ctx->memclk_offset, 514 MEMCLK_EN, 0x0); 515 516 if (!cmu_has_pm) 517 /* 518 * When a CMU has PM support, clocks are saved/restored 519 * via its PM handlers, so only register them with the 520 * syscore suspend / resume paths if PM is not in use. 521 */ 522 samsung_clk_extended_sleep_init(NULL, ctx->sysreg, 523 cmu->sysreg_clk_regs, 524 cmu->nr_sysreg_clk_regs, 525 NULL, 0); 526 } 527 } 528 529 /* 530 * Common function which registers plls, muxes, dividers and gates 531 * for each CMU. It also add CMU register list to register cache. 532 */ 533 struct samsung_clk_provider * __init samsung_cmu_register_one( 534 struct device_node *np, 535 const struct samsung_cmu_info *cmu) 536 { 537 void __iomem *reg_base; 538 struct samsung_clk_provider *ctx; 539 540 reg_base = of_iomap(np, 0); 541 if (!reg_base) { 542 panic("%s: failed to map registers\n", __func__); 543 return NULL; 544 } 545 546 ctx = samsung_clk_init(NULL, reg_base, cmu->nr_clk_ids); 547 samsung_cmu_register_clocks(ctx, cmu, np); 548 549 if (cmu->clk_regs) 550 samsung_clk_extended_sleep_init(reg_base, NULL, 551 cmu->clk_regs, cmu->nr_clk_regs, 552 cmu->suspend_regs, cmu->nr_suspend_regs); 553 554 samsung_clk_of_add_provider(np, ctx); 555 556 /* sysreg DT nodes reference a clock in this CMU */ 557 samsung_en_dyn_root_clk_gating(np, ctx, cmu, false); 558 559 return ctx; 560 } 561