601 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * AM33XX Power Management Routines4 *5 * Copyright (C) 2012-2018 Texas Instruments Incorporated - http://www.ti.com/6 * Vaibhav Bedia, Dave Gerlach7 */8 9#include <linux/clk.h>10#include <linux/cpu.h>11#include <linux/err.h>12#include <linux/genalloc.h>13#include <linux/kernel.h>14#include <linux/init.h>15#include <linux/io.h>16#include <linux/module.h>17#include <linux/nvmem-consumer.h>18#include <linux/of.h>19#include <linux/of_address.h>20#include <linux/platform_data/pm33xx.h>21#include <linux/platform_device.h>22#include <linux/pm_runtime.h>23#include <linux/rtc.h>24#include <linux/rtc/rtc-omap.h>25#include <linux/sizes.h>26#include <linux/sram.h>27#include <linux/suspend.h>28#include <linux/ti-emif-sram.h>29#include <linux/wkup_m3_ipc.h>30 31#include <asm/proc-fns.h>32#include <asm/suspend.h>33#include <asm/system_misc.h>34 35#define AMX3_PM_SRAM_SYMBOL_OFFSET(sym) ((unsigned long)(sym) - \36 (unsigned long)pm_sram->do_wfi)37 38#define RTC_SCRATCH_RESUME_REG 039#define RTC_SCRATCH_MAGIC_REG 140#define RTC_REG_BOOT_MAGIC 0x8cd0 /* RTC */41#define GIC_INT_SET_PENDING_BASE 0x20042#define AM43XX_GIC_DIST_BASE 0x4824100043 44static void __iomem *rtc_base_virt;45static struct clk *rtc_fck;46static u32 rtc_magic_val;47 48static int (*am33xx_do_wfi_sram)(unsigned long unused);49static phys_addr_t am33xx_do_wfi_sram_phys;50 51static struct gen_pool *sram_pool, *sram_pool_data;52static unsigned long ocmcram_location, ocmcram_location_data;53 54static struct rtc_device *omap_rtc;55static void __iomem *gic_dist_base;56 57static struct am33xx_pm_platform_data *pm_ops;58static struct am33xx_pm_sram_addr *pm_sram;59 60static struct device *pm33xx_dev;61static struct wkup_m3_ipc *m3_ipc;62 63#ifdef CONFIG_SUSPEND64static int rtc_only_idle;65static int retrigger_irq;66static unsigned long suspend_wfi_flags;67 68static struct wkup_m3_wakeup_src wakeup_src = {.irq_nr = 0,69 .src = "Unknown",70};71 72static struct wkup_m3_wakeup_src rtc_alarm_wakeup = {73 .irq_nr = 108, .src = "RTC Alarm",74};75 76static struct wkup_m3_wakeup_src rtc_ext_wakeup = {77 .irq_nr = 0, .src = "Ext wakeup",78};79#endif80 81static u32 sram_suspend_address(unsigned long addr)82{83 return ((unsigned long)am33xx_do_wfi_sram +84 AMX3_PM_SRAM_SYMBOL_OFFSET(addr));85}86 87static int am33xx_push_sram_idle(void)88{89 struct am33xx_pm_ro_sram_data ro_sram_data;90 int ret;91 u32 table_addr, ro_data_addr;92 void *copy_addr;93 94 ro_sram_data.amx3_pm_sram_data_virt = ocmcram_location_data;95 ro_sram_data.amx3_pm_sram_data_phys =96 gen_pool_virt_to_phys(sram_pool_data, ocmcram_location_data);97 ro_sram_data.rtc_base_virt = rtc_base_virt;98 99 /* Save physical address to calculate resume offset during pm init */100 am33xx_do_wfi_sram_phys = gen_pool_virt_to_phys(sram_pool,101 ocmcram_location);102 103 am33xx_do_wfi_sram = sram_exec_copy(sram_pool, (void *)ocmcram_location,104 pm_sram->do_wfi,105 *pm_sram->do_wfi_sz);106 if (!am33xx_do_wfi_sram) {107 dev_err(pm33xx_dev,108 "PM: %s: am33xx_do_wfi copy to sram failed\n",109 __func__);110 return -ENODEV;111 }112 113 table_addr =114 sram_suspend_address((unsigned long)pm_sram->emif_sram_table);115 ret = ti_emif_copy_pm_function_table(sram_pool, (void *)table_addr);116 if (ret) {117 dev_dbg(pm33xx_dev,118 "PM: %s: EMIF function copy failed\n", __func__);119 return -EPROBE_DEFER;120 }121 122 ro_data_addr =123 sram_suspend_address((unsigned long)pm_sram->ro_sram_data);124 copy_addr = sram_exec_copy(sram_pool, (void *)ro_data_addr,125 &ro_sram_data,126 sizeof(ro_sram_data));127 if (!copy_addr) {128 dev_err(pm33xx_dev,129 "PM: %s: ro_sram_data copy to sram failed\n",130 __func__);131 return -ENODEV;132 }133 134 return 0;135}136 137static int am33xx_do_sram_idle(u32 wfi_flags)138{139 if (!m3_ipc || !pm_ops)140 return 0;141 142 if (wfi_flags & WFI_FLAG_WAKE_M3)143 m3_ipc->ops->prepare_low_power(m3_ipc, WKUP_M3_IDLE);144 145 return pm_ops->cpu_suspend(am33xx_do_wfi_sram, wfi_flags);146}147 148static int __init am43xx_map_gic(void)149{150 gic_dist_base = ioremap(AM43XX_GIC_DIST_BASE, SZ_4K);151 152 if (!gic_dist_base)153 return -ENOMEM;154 155 return 0;156}157 158#ifdef CONFIG_SUSPEND159static struct wkup_m3_wakeup_src rtc_wake_src(void)160{161 u32 i;162 163 i = __raw_readl(rtc_base_virt + 0x44) & 0x40;164 165 if (i) {166 retrigger_irq = rtc_alarm_wakeup.irq_nr;167 return rtc_alarm_wakeup;168 }169 170 retrigger_irq = rtc_ext_wakeup.irq_nr;171 172 return rtc_ext_wakeup;173}174 175static int am33xx_rtc_only_idle(unsigned long wfi_flags)176{177 omap_rtc_power_off_program(&omap_rtc->dev);178 am33xx_do_wfi_sram(wfi_flags);179 return 0;180}181 182/*183 * Note that the RTC module clock must be re-enabled only for rtc+ddr suspend.184 * And looks like the module can stay in SYSC_IDLE_SMART_WKUP mode configured185 * by the interconnect code just fine for both rtc+ddr suspend and retention186 * suspend.187 */188static int am33xx_pm_suspend(suspend_state_t suspend_state)189{190 int i, ret = 0;191 192 if (suspend_state == PM_SUSPEND_MEM &&193 pm_ops->check_off_mode_enable()) {194 ret = clk_prepare_enable(rtc_fck);195 if (ret) {196 dev_err(pm33xx_dev, "Failed to enable clock: %i\n", ret);197 return ret;198 }199 200 pm_ops->save_context();201 suspend_wfi_flags |= WFI_FLAG_RTC_ONLY;202 clk_save_context();203 ret = pm_ops->soc_suspend(suspend_state, am33xx_rtc_only_idle,204 suspend_wfi_flags);205 206 suspend_wfi_flags &= ~WFI_FLAG_RTC_ONLY;207 dev_info(pm33xx_dev, "Entering RTC Only mode with DDR in self-refresh\n");208 209 if (!ret) {210 clk_restore_context();211 pm_ops->restore_context();212 m3_ipc->ops->set_rtc_only(m3_ipc);213 am33xx_push_sram_idle();214 }215 } else {216 ret = pm_ops->soc_suspend(suspend_state, am33xx_do_wfi_sram,217 suspend_wfi_flags);218 }219 220 if (ret) {221 dev_err(pm33xx_dev, "PM: Kernel suspend failure\n");222 } else {223 i = m3_ipc->ops->request_pm_status(m3_ipc);224 225 switch (i) {226 case 0:227 dev_info(pm33xx_dev,228 "PM: Successfully put all powerdomains to target state\n");229 break;230 case 1:231 dev_err(pm33xx_dev,232 "PM: Could not transition all powerdomains to target state\n");233 ret = -1;234 break;235 default:236 dev_err(pm33xx_dev,237 "PM: CM3 returned unknown result = %d\n", i);238 ret = -1;239 }240 241 /* print the wakeup reason */242 if (rtc_only_idle) {243 wakeup_src = rtc_wake_src();244 pr_info("PM: Wakeup source %s\n", wakeup_src.src);245 } else {246 pr_info("PM: Wakeup source %s\n",247 m3_ipc->ops->request_wake_src(m3_ipc));248 }249 }250 251 if (suspend_state == PM_SUSPEND_MEM && pm_ops->check_off_mode_enable())252 clk_disable_unprepare(rtc_fck);253 254 return ret;255}256 257static int am33xx_pm_enter(suspend_state_t suspend_state)258{259 int ret = 0;260 261 switch (suspend_state) {262 case PM_SUSPEND_MEM:263 case PM_SUSPEND_STANDBY:264 ret = am33xx_pm_suspend(suspend_state);265 break;266 default:267 ret = -EINVAL;268 }269 270 return ret;271}272 273static int am33xx_pm_begin(suspend_state_t state)274{275 int ret = -EINVAL;276 struct nvmem_device *nvmem;277 278 if (state == PM_SUSPEND_MEM && pm_ops->check_off_mode_enable()) {279 nvmem = devm_nvmem_device_get(&omap_rtc->dev,280 "omap_rtc_scratch0");281 if (!IS_ERR(nvmem))282 nvmem_device_write(nvmem, RTC_SCRATCH_MAGIC_REG * 4, 4,283 (void *)&rtc_magic_val);284 rtc_only_idle = 1;285 } else {286 rtc_only_idle = 0;287 }288 289 pm_ops->begin_suspend();290 291 switch (state) {292 case PM_SUSPEND_MEM:293 ret = m3_ipc->ops->prepare_low_power(m3_ipc, WKUP_M3_DEEPSLEEP);294 break;295 case PM_SUSPEND_STANDBY:296 ret = m3_ipc->ops->prepare_low_power(m3_ipc, WKUP_M3_STANDBY);297 break;298 }299 300 return ret;301}302 303static void am33xx_pm_end(void)304{305 u32 val = 0;306 struct nvmem_device *nvmem;307 308 nvmem = devm_nvmem_device_get(&omap_rtc->dev, "omap_rtc_scratch0");309 if (IS_ERR(nvmem))310 return;311 312 m3_ipc->ops->finish_low_power(m3_ipc);313 if (rtc_only_idle) {314 if (retrigger_irq) {315 /*316 * 32 bits of Interrupt Set-Pending correspond to 32317 * 32 interrupts. Compute the bit offset of the318 * Interrupt and set that particular bit319 * Compute the register offset by dividing interrupt320 * number by 32 and mutiplying by 4321 */322 writel_relaxed(1 << (retrigger_irq & 31),323 gic_dist_base + GIC_INT_SET_PENDING_BASE324 + retrigger_irq / 32 * 4);325 }326 327 nvmem_device_write(nvmem, RTC_SCRATCH_MAGIC_REG * 4, 4,328 (void *)&val);329 }330 331 rtc_only_idle = 0;332 333 pm_ops->finish_suspend();334}335 336static int am33xx_pm_valid(suspend_state_t state)337{338 switch (state) {339 case PM_SUSPEND_STANDBY:340 case PM_SUSPEND_MEM:341 return 1;342 default:343 return 0;344 }345}346 347static const struct platform_suspend_ops am33xx_pm_ops = {348 .begin = am33xx_pm_begin,349 .end = am33xx_pm_end,350 .enter = am33xx_pm_enter,351 .valid = am33xx_pm_valid,352};353#endif /* CONFIG_SUSPEND */354 355static void am33xx_pm_set_ipc_ops(void)356{357 u32 resume_address;358 int temp;359 360 temp = ti_emif_get_mem_type();361 if (temp < 0) {362 dev_err(pm33xx_dev, "PM: Cannot determine memory type, no PM available\n");363 return;364 }365 m3_ipc->ops->set_mem_type(m3_ipc, temp);366 367 /* Physical resume address to be used by ROM code */368 resume_address = am33xx_do_wfi_sram_phys +369 *pm_sram->resume_offset + 0x4;370 371 m3_ipc->ops->set_resume_address(m3_ipc, (void *)resume_address);372}373 374static void am33xx_pm_free_sram(void)375{376 gen_pool_free(sram_pool, ocmcram_location, *pm_sram->do_wfi_sz);377 gen_pool_free(sram_pool_data, ocmcram_location_data,378 sizeof(struct am33xx_pm_ro_sram_data));379}380 381/*382 * Push the minimal suspend-resume code to SRAM383 */384static int am33xx_pm_alloc_sram(void)385{386 struct device_node *np __free(device_node) =387 of_find_compatible_node(NULL, NULL, "ti,omap3-mpu");388 389 if (!np) {390 np = of_find_compatible_node(NULL, NULL, "ti,omap4-mpu");391 if (!np)392 return dev_err_probe(pm33xx_dev, -ENODEV,393 "PM: %s: Unable to find device node for mpu\n",394 __func__);395 }396 397 sram_pool = of_gen_pool_get(np, "pm-sram", 0);398 if (!sram_pool)399 return dev_err_probe(pm33xx_dev, -ENODEV,400 "PM: %s: Unable to get sram pool for ocmcram\n",401 __func__);402 403 sram_pool_data = of_gen_pool_get(np, "pm-sram", 1);404 if (!sram_pool_data)405 return dev_err_probe(pm33xx_dev, -ENODEV,406 "PM: %s: Unable to get sram data pool for ocmcram\n",407 __func__);408 409 ocmcram_location = gen_pool_alloc(sram_pool, *pm_sram->do_wfi_sz);410 if (!ocmcram_location)411 return dev_err_probe(pm33xx_dev, -ENOMEM,412 "PM: %s: Unable to allocate memory from ocmcram\n",413 __func__);414 415 ocmcram_location_data = gen_pool_alloc(sram_pool_data,416 sizeof(struct emif_regs_amx3));417 if (!ocmcram_location_data) {418 gen_pool_free(sram_pool, ocmcram_location, *pm_sram->do_wfi_sz);419 return dev_err_probe(pm33xx_dev, -ENOMEM,420 "PM: Unable to allocate memory from ocmcram\n");421 }422 423 return 0;424}425 426static int am33xx_pm_rtc_setup(void)427{428 struct device_node *np;429 unsigned long val = 0;430 struct nvmem_device *nvmem;431 int error;432 433 np = of_find_node_by_name(NULL, "rtc");434 435 if (of_device_is_available(np)) {436 /* RTC interconnect target module clock */437 rtc_fck = of_clk_get_by_name(np->parent, "fck");438 if (IS_ERR(rtc_fck))439 return PTR_ERR(rtc_fck);440 441 rtc_base_virt = of_iomap(np, 0);442 if (!rtc_base_virt) {443 pr_warn("PM: could not iomap rtc\n");444 error = -ENODEV;445 goto err_clk_put;446 }447 448 omap_rtc = rtc_class_open("rtc0");449 if (!omap_rtc) {450 pr_warn("PM: rtc0 not available\n");451 error = -EPROBE_DEFER;452 goto err_iounmap;453 }454 455 nvmem = devm_nvmem_device_get(&omap_rtc->dev,456 "omap_rtc_scratch0");457 if (!IS_ERR(nvmem)) {458 nvmem_device_read(nvmem, RTC_SCRATCH_MAGIC_REG * 4,459 4, (void *)&rtc_magic_val);460 if ((rtc_magic_val & 0xffff) != RTC_REG_BOOT_MAGIC)461 pr_warn("PM: bootloader does not support rtc-only!\n");462 463 nvmem_device_write(nvmem, RTC_SCRATCH_MAGIC_REG * 4,464 4, (void *)&val);465 val = pm_sram->resume_address;466 nvmem_device_write(nvmem, RTC_SCRATCH_RESUME_REG * 4,467 4, (void *)&val);468 }469 } else {470 pr_warn("PM: no-rtc available, rtc-only mode disabled.\n");471 }472 473 return 0;474 475err_iounmap:476 iounmap(rtc_base_virt);477err_clk_put:478 clk_put(rtc_fck);479 480 return error;481}482 483static int am33xx_pm_probe(struct platform_device *pdev)484{485 struct device *dev = &pdev->dev;486 int ret;487 488 if (!of_machine_is_compatible("ti,am33xx") &&489 !of_machine_is_compatible("ti,am43"))490 return -ENODEV;491 492 pm_ops = dev->platform_data;493 if (!pm_ops) {494 dev_err(dev, "PM: Cannot get core PM ops!\n");495 return -ENODEV;496 }497 498 ret = am43xx_map_gic();499 if (ret) {500 pr_err("PM: Could not ioremap GIC base\n");501 return ret;502 }503 504 pm_sram = pm_ops->get_sram_addrs();505 if (!pm_sram) {506 dev_err(dev, "PM: Cannot get PM asm function addresses!!\n");507 return -ENODEV;508 }509 510 m3_ipc = wkup_m3_ipc_get();511 if (!m3_ipc) {512 pr_err("PM: Cannot get wkup_m3_ipc handle\n");513 return -EPROBE_DEFER;514 }515 516 pm33xx_dev = dev;517 518 ret = am33xx_pm_alloc_sram();519 if (ret)520 goto err_wkup_m3_ipc_put;521 522 ret = am33xx_pm_rtc_setup();523 if (ret)524 goto err_free_sram;525 526 ret = am33xx_push_sram_idle();527 if (ret)528 goto err_unsetup_rtc;529 530 am33xx_pm_set_ipc_ops();531 532#ifdef CONFIG_SUSPEND533 suspend_set_ops(&am33xx_pm_ops);534 535 /*536 * For a system suspend we must flush the caches, we want537 * the DDR in self-refresh, we want to save the context538 * of the EMIF, and we want the wkup_m3 to handle low-power539 * transition.540 */541 suspend_wfi_flags |= WFI_FLAG_FLUSH_CACHE;542 suspend_wfi_flags |= WFI_FLAG_SELF_REFRESH;543 suspend_wfi_flags |= WFI_FLAG_SAVE_EMIF;544 suspend_wfi_flags |= WFI_FLAG_WAKE_M3;545#endif /* CONFIG_SUSPEND */546 547 pm_runtime_enable(dev);548 ret = pm_runtime_resume_and_get(dev);549 if (ret < 0)550 goto err_pm_runtime_disable;551 552 ret = pm_ops->init(am33xx_do_sram_idle);553 if (ret) {554 dev_err(dev, "Unable to call core pm init!\n");555 ret = -ENODEV;556 goto err_pm_runtime_put;557 }558 559 return 0;560 561err_pm_runtime_put:562 pm_runtime_put_sync(dev);563err_pm_runtime_disable:564 pm_runtime_disable(dev);565err_unsetup_rtc:566 iounmap(rtc_base_virt);567 clk_put(rtc_fck);568err_free_sram:569 am33xx_pm_free_sram();570 pm33xx_dev = NULL;571err_wkup_m3_ipc_put:572 wkup_m3_ipc_put(m3_ipc);573 return ret;574}575 576static void am33xx_pm_remove(struct platform_device *pdev)577{578 pm_runtime_put_sync(&pdev->dev);579 pm_runtime_disable(&pdev->dev);580 if (pm_ops->deinit)581 pm_ops->deinit();582 suspend_set_ops(NULL);583 wkup_m3_ipc_put(m3_ipc);584 am33xx_pm_free_sram();585 iounmap(rtc_base_virt);586 clk_put(rtc_fck);587}588 589static struct platform_driver am33xx_pm_driver = {590 .driver = {591 .name = "pm33xx",592 },593 .probe = am33xx_pm_probe,594 .remove_new = am33xx_pm_remove,595};596module_platform_driver(am33xx_pm_driver);597 598MODULE_ALIAS("platform:pm33xx");599MODULE_LICENSE("GPL v2");600MODULE_DESCRIPTION("am33xx power management driver");601