1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // Copyright (c) 2011-2014 Samsung Electronics Co., Ltd. 4 // http://www.samsung.com/ 5 // 6 // Exynos - CPU PMU(Power Management Unit) support 7 8 #include <linux/array_size.h> 9 #include <linux/bitmap.h> 10 #include <linux/cpuhotplug.h> 11 #include <linux/cpu_pm.h> 12 #include <linux/of.h> 13 #include <linux/of_address.h> 14 #include <linux/mfd/core.h> 15 #include <linux/mfd/syscon.h> 16 #include <linux/of_platform.h> 17 #include <linux/platform_device.h> 18 #include <linux/delay.h> 19 #include <linux/reboot.h> 20 #include <linux/regmap.h> 21 22 #include <linux/soc/samsung/exynos-regs-pmu.h> 23 #include <linux/soc/samsung/exynos-pmu.h> 24 25 #include "exynos-pmu.h" 26 27 struct exynos_pmu_context { 28 struct device *dev; 29 const struct exynos_pmu_data *pmu_data; 30 struct regmap *pmureg; 31 struct regmap *pmuintrgen; 32 /* 33 * Serialization lock for CPU hot plug and cpuidle ACPM hint 34 * programming. Also protects in_cpuhp, sys_insuspend & sys_inreboot 35 * flags. 36 */ 37 raw_spinlock_t cpupm_lock; 38 unsigned long *in_cpuhp; 39 bool sys_insuspend; 40 bool sys_inreboot; 41 int cpuhp_prepare_state; 42 int cpuhp_online_state; 43 }; 44 45 void __iomem *pmu_base_addr; 46 static struct exynos_pmu_context *pmu_context; 47 /* forward declaration */ 48 static struct platform_driver exynos_pmu_driver; 49 50 void pmu_raw_writel(u32 val, u32 offset) 51 { 52 writel_relaxed(val, pmu_base_addr + offset); 53 } 54 55 u32 pmu_raw_readl(u32 offset) 56 { 57 return readl_relaxed(pmu_base_addr + offset); 58 } 59 60 void exynos_sys_powerdown_conf(enum sys_powerdown mode) 61 { 62 unsigned int i; 63 const struct exynos_pmu_data *pmu_data; 64 struct exynos_pmu_context *ctx; 65 66 /* Pairs with the smp_store_release() in exynos_pmu_probe(). */ 67 ctx = smp_load_acquire(&pmu_context); 68 if (!ctx || !ctx->pmu_data) 69 return; 70 71 pmu_data = ctx->pmu_data; 72 73 if (pmu_data->powerdown_conf) 74 pmu_data->powerdown_conf(mode); 75 76 if (pmu_data->pmu_config) { 77 for (i = 0; (pmu_data->pmu_config[i].offset != PMU_TABLE_END); i++) 78 pmu_raw_writel(pmu_data->pmu_config[i].val[mode], 79 pmu_data->pmu_config[i].offset); 80 } 81 82 if (pmu_data->powerdown_conf_extra) 83 pmu_data->powerdown_conf_extra(mode); 84 85 if (pmu_data->pmu_config_extra) { 86 for (i = 0; pmu_data->pmu_config_extra[i].offset != PMU_TABLE_END; i++) 87 pmu_raw_writel(pmu_data->pmu_config_extra[i].val[mode], 88 pmu_data->pmu_config_extra[i].offset); 89 } 90 } 91 92 /* 93 * Split the data between ARM architectures because it is relatively big 94 * and useless on other arch. 95 */ 96 #ifdef CONFIG_EXYNOS_PMU_ARM_DRIVERS 97 #define exynos_pmu_data_arm_ptr(data) (&data) 98 #else 99 #define exynos_pmu_data_arm_ptr(data) NULL 100 #endif 101 102 static const struct regmap_config regmap_smccfg = { 103 .name = "pmu_regs", 104 .reg_bits = 32, 105 .reg_stride = 4, 106 .val_bits = 32, 107 .fast_io = true, 108 .use_single_read = true, 109 .use_single_write = true, 110 .reg_read = tensor_sec_reg_read, 111 .reg_write = tensor_sec_reg_write, 112 .reg_update_bits = tensor_sec_update_bits, 113 .use_raw_spinlock = true, 114 }; 115 116 static const struct regmap_config regmap_pmu_intr = { 117 .name = "pmu_intr_gen", 118 .reg_bits = 32, 119 .reg_stride = 4, 120 .val_bits = 32, 121 .use_raw_spinlock = true, 122 }; 123 124 /* 125 * PMU platform driver and devicetree bindings. 126 */ 127 static const struct of_device_id exynos_pmu_of_device_ids[] = { 128 { 129 .compatible = "google,gs101-pmu", 130 .data = &gs101_pmu_data, 131 }, { 132 .compatible = "samsung,exynos3250-pmu", 133 .data = exynos_pmu_data_arm_ptr(exynos3250_pmu_data), 134 }, { 135 .compatible = "samsung,exynos4210-pmu", 136 .data = exynos_pmu_data_arm_ptr(exynos4210_pmu_data), 137 }, { 138 .compatible = "samsung,exynos4212-pmu", 139 .data = exynos_pmu_data_arm_ptr(exynos4212_pmu_data), 140 }, { 141 .compatible = "samsung,exynos4412-pmu", 142 .data = exynos_pmu_data_arm_ptr(exynos4412_pmu_data), 143 }, { 144 .compatible = "samsung,exynos5250-pmu", 145 .data = exynos_pmu_data_arm_ptr(exynos5250_pmu_data), 146 }, { 147 .compatible = "samsung,exynos5410-pmu", 148 }, { 149 .compatible = "samsung,exynos5420-pmu", 150 .data = exynos_pmu_data_arm_ptr(exynos5420_pmu_data), 151 }, { 152 .compatible = "samsung,exynos5433-pmu", 153 }, { 154 .compatible = "samsung,exynos7-pmu", 155 }, { 156 .compatible = "samsung,exynos850-pmu", 157 }, 158 { /*sentinel*/ }, 159 }; 160 161 static const struct mfd_cell exynos_pmu_devs[] = { 162 { .name = "exynos-clkout", }, 163 }; 164 165 /** 166 * exynos_get_pmu_regmap() - Obtain pmureg regmap 167 * 168 * Find the pmureg regmap previously configured in probe() and return regmap 169 * pointer. 170 * 171 * Return: A pointer to regmap if found or ERR_PTR error value. 172 */ 173 struct regmap *exynos_get_pmu_regmap(void) 174 { 175 struct device_node *np __free(device_node) = 176 of_find_matching_node(NULL, exynos_pmu_of_device_ids); 177 if (np) 178 return exynos_get_pmu_regmap_by_phandle(np, NULL); 179 return ERR_PTR(-ENODEV); 180 } 181 EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap); 182 183 /** 184 * exynos_get_pmu_regmap_by_phandle() - Obtain pmureg regmap via phandle 185 * @np: Device node holding PMU phandle property 186 * @propname: Name of property holding phandle value 187 * 188 * Find the pmureg regmap previously configured in probe() and return regmap 189 * pointer. 190 * 191 * Return: A pointer to regmap if found or ERR_PTR error value. 192 */ 193 struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np, 194 const char *propname) 195 { 196 struct device_node *pmu_np; 197 struct device *dev; 198 199 if (propname) 200 pmu_np = of_parse_phandle(np, propname, 0); 201 else 202 pmu_np = np; 203 204 if (!pmu_np) 205 return ERR_PTR(-ENODEV); 206 207 /* 208 * Determine if exynos-pmu device has probed and therefore regmap 209 * has been created and can be returned to the caller. Otherwise we 210 * return -EPROBE_DEFER. 211 */ 212 dev = driver_find_device_by_of_node(&exynos_pmu_driver.driver, 213 (void *)pmu_np); 214 215 if (propname) 216 of_node_put(pmu_np); 217 218 if (!dev) 219 return ERR_PTR(-EPROBE_DEFER); 220 221 put_device(dev); 222 223 return syscon_node_to_regmap(pmu_np); 224 } 225 EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap_by_phandle); 226 227 /* 228 * CPU_INFORM register "hint" values are required to be programmed in addition to 229 * the standard PSCI calls to have functional CPU hotplug and CPU idle states. 230 * This is required to workaround limitations in the el3mon/ACPM firmware. 231 */ 232 #define CPU_INFORM_CLEAR 0 233 #define CPU_INFORM_C2 1 234 235 /* 236 * __gs101_cpu_pmu_ prefix functions are common code shared by CPU PM notifiers 237 * (CPUIdle) and CPU hotplug callbacks. Functions should be called with IRQs 238 * disabled and cpupm_lock held. 239 */ 240 static int __gs101_cpu_pmu_online(unsigned int cpu) 241 __must_hold(&pmu_context->cpupm_lock) 242 { 243 unsigned int cpuhint = smp_processor_id(); 244 u32 reg, mask; 245 246 /* clear cpu inform hint */ 247 regmap_write(pmu_context->pmureg, GS101_CPU_INFORM(cpuhint), 248 CPU_INFORM_CLEAR); 249 250 mask = BIT(cpu); 251 252 regmap_update_bits(pmu_context->pmuintrgen, GS101_GRP2_INTR_BID_ENABLE, 253 mask, (0 << cpu)); 254 255 regmap_read(pmu_context->pmuintrgen, GS101_GRP2_INTR_BID_UPEND, ®); 256 257 regmap_write(pmu_context->pmuintrgen, GS101_GRP2_INTR_BID_CLEAR, 258 reg & mask); 259 260 return 0; 261 } 262 263 /* Called from CPU PM notifier (CPUIdle code path) with IRQs disabled */ 264 static int gs101_cpu_pmu_online(void) 265 { 266 int cpu; 267 268 raw_spin_lock(&pmu_context->cpupm_lock); 269 270 if (pmu_context->sys_inreboot) { 271 raw_spin_unlock(&pmu_context->cpupm_lock); 272 return NOTIFY_OK; 273 } 274 275 cpu = smp_processor_id(); 276 __gs101_cpu_pmu_online(cpu); 277 raw_spin_unlock(&pmu_context->cpupm_lock); 278 279 return NOTIFY_OK; 280 } 281 282 /* Called from CPU hot plug callback with IRQs enabled */ 283 static int gs101_cpuhp_pmu_online(unsigned int cpu) 284 { 285 unsigned long flags; 286 287 raw_spin_lock_irqsave(&pmu_context->cpupm_lock, flags); 288 289 __gs101_cpu_pmu_online(cpu); 290 /* 291 * Mark this CPU as having finished the hotplug. 292 * This means this CPU can now enter C2 idle state. 293 */ 294 clear_bit(cpu, pmu_context->in_cpuhp); 295 raw_spin_unlock_irqrestore(&pmu_context->cpupm_lock, flags); 296 297 return 0; 298 } 299 300 /* Common function shared by both CPU hot plug and CPUIdle */ 301 static int __gs101_cpu_pmu_offline(unsigned int cpu) 302 __must_hold(&pmu_context->cpupm_lock) 303 { 304 unsigned int cpuhint = smp_processor_id(); 305 u32 reg, mask; 306 307 /* set cpu inform hint */ 308 regmap_write(pmu_context->pmureg, GS101_CPU_INFORM(cpuhint), 309 CPU_INFORM_C2); 310 311 mask = BIT(cpu); 312 regmap_update_bits(pmu_context->pmuintrgen, GS101_GRP2_INTR_BID_ENABLE, 313 mask, BIT(cpu)); 314 315 regmap_read(pmu_context->pmuintrgen, GS101_GRP1_INTR_BID_UPEND, ®); 316 regmap_write(pmu_context->pmuintrgen, GS101_GRP1_INTR_BID_CLEAR, 317 reg & mask); 318 319 mask = (BIT(cpu + 8)); 320 regmap_read(pmu_context->pmuintrgen, GS101_GRP1_INTR_BID_UPEND, ®); 321 regmap_write(pmu_context->pmuintrgen, GS101_GRP1_INTR_BID_CLEAR, 322 reg & mask); 323 324 return 0; 325 } 326 327 /* Called from CPU PM notifier (CPUIdle code path) with IRQs disabled */ 328 static int gs101_cpu_pmu_offline(void) 329 { 330 int cpu; 331 332 raw_spin_lock(&pmu_context->cpupm_lock); 333 cpu = smp_processor_id(); 334 335 if (test_bit(cpu, pmu_context->in_cpuhp)) { 336 raw_spin_unlock(&pmu_context->cpupm_lock); 337 return NOTIFY_BAD; 338 } 339 340 /* Ignore CPU_PM_ENTER event in reboot or suspend sequence. */ 341 if (pmu_context->sys_insuspend || pmu_context->sys_inreboot) { 342 raw_spin_unlock(&pmu_context->cpupm_lock); 343 return NOTIFY_OK; 344 } 345 346 __gs101_cpu_pmu_offline(cpu); 347 raw_spin_unlock(&pmu_context->cpupm_lock); 348 349 return NOTIFY_OK; 350 } 351 352 /* Called from CPU hot plug callback with IRQs enabled */ 353 static int gs101_cpuhp_pmu_offline(unsigned int cpu) 354 { 355 unsigned long flags; 356 357 raw_spin_lock_irqsave(&pmu_context->cpupm_lock, flags); 358 /* 359 * Mark this CPU as entering hotplug. So as not to confuse 360 * ACPM the CPU entering hotplug should not enter C2 idle state. 361 */ 362 set_bit(cpu, pmu_context->in_cpuhp); 363 __gs101_cpu_pmu_offline(cpu); 364 365 raw_spin_unlock_irqrestore(&pmu_context->cpupm_lock, flags); 366 367 return 0; 368 } 369 370 static int gs101_cpu_pm_notify_callback(struct notifier_block *self, 371 unsigned long action, void *v) 372 { 373 switch (action) { 374 case CPU_PM_ENTER: 375 return gs101_cpu_pmu_offline(); 376 377 case CPU_PM_EXIT: 378 return gs101_cpu_pmu_online(); 379 } 380 381 return NOTIFY_OK; 382 } 383 384 static struct notifier_block gs101_cpu_pm_notifier = { 385 .notifier_call = gs101_cpu_pm_notify_callback, 386 /* 387 * We want to be called first, as the ACPM hint and handshake is what 388 * puts the CPU into C2. 389 */ 390 .priority = INT_MAX 391 }; 392 393 static int exynos_cpupm_reboot_notifier(struct notifier_block *nb, 394 unsigned long event, void *v) 395 { 396 unsigned long flags; 397 398 switch (event) { 399 case SYS_POWER_OFF: 400 case SYS_RESTART: 401 raw_spin_lock_irqsave(&pmu_context->cpupm_lock, flags); 402 pmu_context->sys_inreboot = true; 403 raw_spin_unlock_irqrestore(&pmu_context->cpupm_lock, flags); 404 break; 405 } 406 407 return NOTIFY_OK; 408 } 409 410 static struct notifier_block exynos_cpupm_reboot_nb = { 411 .priority = INT_MAX, 412 .notifier_call = exynos_cpupm_reboot_notifier, 413 }; 414 415 static int setup_cpuhp_and_cpuidle(struct device *dev) 416 { 417 struct device_node *intr_gen_node __free(device_node) = 418 of_parse_phandle(dev->of_node, "google,pmu-intr-gen-syscon", 0); 419 struct resource intrgen_res; 420 void __iomem *virt_addr; 421 int ret, cpu; 422 423 if (!intr_gen_node) { 424 /* 425 * To maintain support for older DTs that didn't specify syscon 426 * phandle just issue a warning rather than fail to probe. 427 */ 428 dev_warn(dev, "pmu-intr-gen syscon unavailable\n"); 429 return 0; 430 } 431 432 /* 433 * To avoid lockdep issues (CPU PM notifiers use raw spinlocks) create 434 * a mmio regmap for pmu-intr-gen that uses raw spinlocks instead of 435 * syscon provided regmap. 436 */ 437 ret = of_address_to_resource(intr_gen_node, 0, &intrgen_res); 438 virt_addr = devm_ioremap(dev, intrgen_res.start, 439 resource_size(&intrgen_res)); 440 if (!virt_addr) 441 return -ENOMEM; 442 443 pmu_context->pmuintrgen = devm_regmap_init_mmio(dev, virt_addr, 444 ®map_pmu_intr); 445 if (IS_ERR(pmu_context->pmuintrgen)) { 446 dev_err(dev, "failed to initialize pmu-intr-gen regmap\n"); 447 return PTR_ERR(pmu_context->pmuintrgen); 448 } 449 450 /* register custom mmio regmap with syscon */ 451 ret = of_syscon_register_regmap(intr_gen_node, 452 pmu_context->pmuintrgen); 453 if (ret) 454 return ret; 455 456 pmu_context->in_cpuhp = devm_bitmap_zalloc(dev, num_possible_cpus(), 457 GFP_KERNEL); 458 if (!pmu_context->in_cpuhp) 459 return -ENOMEM; 460 461 /* set PMU to power on */ 462 for_each_online_cpu(cpu) 463 gs101_cpuhp_pmu_online(cpu); 464 465 /* register CPU hotplug callbacks */ 466 pmu_context->cpuhp_prepare_state = CPUHP_INVALID; 467 pmu_context->cpuhp_online_state = CPUHP_INVALID; 468 469 ret = cpuhp_setup_state(CPUHP_BP_PREPARE_DYN, "soc/exynos-pmu:prepare", 470 gs101_cpuhp_pmu_online, NULL); 471 if (ret < 0) 472 return ret; 473 474 pmu_context->cpuhp_prepare_state = ret; 475 476 ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "soc/exynos-pmu:online", 477 NULL, gs101_cpuhp_pmu_offline); 478 if (ret < 0) 479 goto clean_cpuhp_state_prepare; 480 481 pmu_context->cpuhp_online_state = ret; 482 483 /* register CPU PM notifiers for cpuidle */ 484 ret = cpu_pm_register_notifier(&gs101_cpu_pm_notifier); 485 if (ret) 486 goto clean_cpuhp_states; 487 488 ret = register_reboot_notifier(&exynos_cpupm_reboot_nb); 489 if (!ret) 490 /* Success */ 491 return ret; 492 493 cpu_pm_unregister_notifier(&gs101_cpu_pm_notifier); 494 495 clean_cpuhp_states: 496 cpuhp_remove_state(pmu_context->cpuhp_online_state); 497 pmu_context->cpuhp_online_state = CPUHP_INVALID; 498 499 clean_cpuhp_state_prepare: 500 cpuhp_remove_state(pmu_context->cpuhp_prepare_state); 501 pmu_context->cpuhp_prepare_state = CPUHP_INVALID; 502 503 return ret; 504 } 505 506 static void destroy_cpuhp_and_cpuidle(void) 507 { 508 cpu_pm_unregister_notifier(&gs101_cpu_pm_notifier); 509 unregister_reboot_notifier(&exynos_cpupm_reboot_nb); 510 511 if (pmu_context->cpuhp_prepare_state != CPUHP_INVALID) 512 cpuhp_remove_state(pmu_context->cpuhp_prepare_state); 513 if (pmu_context->cpuhp_online_state != CPUHP_INVALID) 514 cpuhp_remove_state(pmu_context->cpuhp_online_state); 515 } 516 517 static int exynos_pmu_probe(struct platform_device *pdev) 518 { 519 struct device *dev = &pdev->dev; 520 struct regmap_config pmu_regmcfg; 521 struct exynos_pmu_context *ctx; 522 struct regmap *regmap; 523 struct resource *res; 524 int ret; 525 526 pmu_base_addr = devm_platform_ioremap_resource(pdev, 0); 527 if (IS_ERR(pmu_base_addr)) 528 return PTR_ERR(pmu_base_addr); 529 530 ctx = devm_kzalloc(&pdev->dev, sizeof(struct exynos_pmu_context), 531 GFP_KERNEL); 532 if (!ctx) 533 return -ENOMEM; 534 535 /* 536 * exynos_sys_powerdown_conf() gates on pmu_context and then writes 537 * through pmu_base_addr, which is a separate global. Publish the 538 * context with release semantics so that the mapping is visible to 539 * a CPU that passes the gate. 540 */ 541 smp_store_release(&pmu_context, ctx); 542 543 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 544 if (!res) 545 return -ENODEV; 546 547 pmu_context->pmu_data = of_device_get_match_data(dev); 548 549 /* For SoCs that secure PMU register writes use custom regmap */ 550 if (pmu_context->pmu_data && pmu_context->pmu_data->pmu_secure) { 551 pmu_regmcfg = regmap_smccfg; 552 pmu_regmcfg.max_register = resource_size(res) - 553 pmu_regmcfg.reg_stride; 554 pmu_regmcfg.wr_table = pmu_context->pmu_data->wr_table; 555 pmu_regmcfg.rd_table = pmu_context->pmu_data->rd_table; 556 557 /* Need physical address for SMC call */ 558 regmap = devm_regmap_init(dev, NULL, 559 (void *)(uintptr_t)res->start, 560 &pmu_regmcfg); 561 562 if (IS_ERR(regmap)) 563 return dev_err_probe(&pdev->dev, PTR_ERR(regmap), 564 "regmap init failed\n"); 565 566 ret = of_syscon_register_regmap(dev->of_node, regmap); 567 if (ret) 568 return ret; 569 } else { 570 /* let syscon create mmio regmap */ 571 regmap = syscon_node_to_regmap(dev->of_node); 572 if (IS_ERR(regmap)) 573 return dev_err_probe(&pdev->dev, PTR_ERR(regmap), 574 "syscon_node_to_regmap failed\n"); 575 } 576 577 pmu_context->pmureg = regmap; 578 pmu_context->dev = dev; 579 raw_spin_lock_init(&pmu_context->cpupm_lock); 580 pmu_context->sys_inreboot = false; 581 pmu_context->sys_insuspend = false; 582 583 if (pmu_context->pmu_data && pmu_context->pmu_data->pmu_cpuhp) { 584 ret = setup_cpuhp_and_cpuidle(dev); 585 if (ret) 586 return ret; 587 } 588 589 if (pmu_context->pmu_data && pmu_context->pmu_data->pmu_init) 590 pmu_context->pmu_data->pmu_init(); 591 592 platform_set_drvdata(pdev, pmu_context); 593 594 ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, exynos_pmu_devs, 595 ARRAY_SIZE(exynos_pmu_devs), NULL, 0, NULL); 596 if (ret) { 597 if (pmu_context->pmu_data && pmu_context->pmu_data->pmu_cpuhp) 598 destroy_cpuhp_and_cpuidle(); 599 600 return ret; 601 } 602 603 if (devm_of_platform_populate(dev)) 604 dev_err(dev, "Error populating children, reboot and poweroff might not work properly\n"); 605 606 dev_dbg(dev, "Exynos PMU Driver probe done\n"); 607 return 0; 608 } 609 610 static int exynos_cpupm_suspend_noirq(struct device *dev) 611 { 612 raw_spin_lock(&pmu_context->cpupm_lock); 613 pmu_context->sys_insuspend = true; 614 raw_spin_unlock(&pmu_context->cpupm_lock); 615 return 0; 616 } 617 618 static int exynos_cpupm_resume_noirq(struct device *dev) 619 { 620 raw_spin_lock(&pmu_context->cpupm_lock); 621 pmu_context->sys_insuspend = false; 622 raw_spin_unlock(&pmu_context->cpupm_lock); 623 return 0; 624 } 625 626 static const struct dev_pm_ops cpupm_pm_ops = { 627 NOIRQ_SYSTEM_SLEEP_PM_OPS(exynos_cpupm_suspend_noirq, 628 exynos_cpupm_resume_noirq) 629 }; 630 631 static struct platform_driver exynos_pmu_driver = { 632 .driver = { 633 .name = "exynos-pmu", 634 .of_match_table = exynos_pmu_of_device_ids, 635 .pm = pm_sleep_ptr(&cpupm_pm_ops), 636 }, 637 .probe = exynos_pmu_probe, 638 }; 639 640 static int __init exynos_pmu_init(void) 641 { 642 return platform_driver_register(&exynos_pmu_driver); 643 644 } 645 postcore_initcall(exynos_pmu_init); 646