root/drivers/soc/ti/pm33xx.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sram_suspend_address
  2. am33xx_push_sram_idle
  3. am43xx_map_gic
  4. rtc_wake_src
  5. am33xx_rtc_only_idle
  6. am33xx_pm_suspend
  7. am33xx_pm_enter
  8. am33xx_pm_begin
  9. am33xx_pm_end
  10. am33xx_pm_valid
  11. am33xx_pm_set_ipc_ops
  12. am33xx_pm_free_sram
  13. am33xx_pm_alloc_sram
  14. am33xx_pm_rtc_setup
  15. am33xx_pm_probe
  16. am33xx_pm_remove

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

/* [<][>][^][v][top][bottom][index][help] */