]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - rpmsg/hwspinlock.git/blob - drivers/soc/ti/pm33xx.c
soc: ti: pm33xx: Add base cpuidle support
[rpmsg/hwspinlock.git] / drivers / soc / ti / pm33xx.c
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  */
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/sizes.h>
23 #include <linux/sram.h>
24 #include <linux/suspend.h>
25 #include <linux/ti-emif-sram.h>
26 #include <linux/wkup_m3_ipc.h>
28 #include <asm/proc-fns.h>
29 #include <asm/suspend.h>
30 #include <asm/system_misc.h>
32 #define AMX3_PM_SRAM_SYMBOL_OFFSET(sym) ((unsigned long)(sym) - \
33                                          (unsigned long)pm_sram->do_wfi)
35 #define RTC_SCRATCH_RESUME_REG  0
36 #define RTC_SCRATCH_MAGIC_REG   1
37 #define RTC_REG_BOOT_MAGIC      0x8cd0 /* RTC */
38 #define GIC_INT_SET_PENDING_BASE 0x200
39 #define AM43XX_GIC_DIST_BASE    0x48241000
41 static u32 rtc_magic_val;
43 static int (*am33xx_do_wfi_sram)(unsigned long unused);
44 static phys_addr_t am33xx_do_wfi_sram_phys;
46 static struct gen_pool *sram_pool, *sram_pool_data;
47 static unsigned long ocmcram_location, ocmcram_location_data;
49 static struct rtc_device *omap_rtc;
50 static void __iomem *gic_dist_base;
52 static struct am33xx_pm_platform_data *pm_ops;
53 static struct am33xx_pm_sram_addr *pm_sram;
55 static struct device *pm33xx_dev;
56 static struct wkup_m3_ipc *m3_ipc;
58 #ifdef CONFIG_SUSPEND
60 static int rtc_only_idle;
61 static int retrigger_irq;
63 static unsigned long suspend_wfi_flags;
65 static struct wkup_m3_wakeup_src wakeup_src = {.irq_nr = 0,
66         .src = "Unknown",
67 };
69 static struct wkup_m3_wakeup_src rtc_alarm_wakeup = {
70         .irq_nr = 108, .src = "RTC Alarm",
71 };
73 static struct wkup_m3_wakeup_src rtc_ext_wakeup = {
74         .irq_nr = 0, .src = "Ext wakeup",
75 };
77 #endif
79 static u32 sram_suspend_address(unsigned long addr)
80 {
81         return ((unsigned long)am33xx_do_wfi_sram +
82                 AMX3_PM_SRAM_SYMBOL_OFFSET(addr));
83 }
85 static int am33xx_push_sram_idle(void)
86 {
87         struct am33xx_pm_ro_sram_data ro_sram_data;
88         int ret;
89         u32 table_addr, ro_data_addr;
90         void *copy_addr;
92         ro_sram_data.amx3_pm_sram_data_virt = ocmcram_location_data;
93         ro_sram_data.amx3_pm_sram_data_phys =
94                 gen_pool_virt_to_phys(sram_pool_data, ocmcram_location_data);
95         ro_sram_data.rtc_base_virt = pm_ops->get_rtc_base_addr();
97         /* Save physical address to calculate resume offset during pm init */
98         am33xx_do_wfi_sram_phys = gen_pool_virt_to_phys(sram_pool,
99                                                         ocmcram_location);
101         am33xx_do_wfi_sram = sram_exec_copy(sram_pool, (void *)ocmcram_location,
102                                             pm_sram->do_wfi,
103                                             *pm_sram->do_wfi_sz);
104         if (!am33xx_do_wfi_sram) {
105                 dev_err(pm33xx_dev,
106                         "PM: %s: am33xx_do_wfi copy to sram failed\n",
107                         __func__);
108                 return -ENODEV;
109         }
111         table_addr =
112                 sram_suspend_address((unsigned long)pm_sram->emif_sram_table);
113         ret = ti_emif_copy_pm_function_table(sram_pool, (void *)table_addr);
114         if (ret) {
115                 dev_dbg(pm33xx_dev,
116                         "PM: %s: EMIF function copy failed\n", __func__);
117                 return -EPROBE_DEFER;
118         }
120         ro_data_addr =
121                 sram_suspend_address((unsigned long)pm_sram->ro_sram_data);
122         copy_addr = sram_exec_copy(sram_pool, (void *)ro_data_addr,
123                                    &ro_sram_data,
124                                    sizeof(ro_sram_data));
125         if (!copy_addr) {
126                 dev_err(pm33xx_dev,
127                         "PM: %s: ro_sram_data copy to sram failed\n",
128                         __func__);
129                 return -ENODEV;
130         }
132         return 0;
135 static int am33xx_do_sram_idle(u32 wfi_flags)
137         int ret = 0;
139         if (!m3_ipc || !pm_ops)
140                 return 0;
142         if (wfi_flags & WFI_FLAG_WAKE_M3)
143                 ret = m3_ipc->ops->prepare_low_power(m3_ipc, WKUP_M3_IDLE);
145         return pm_ops->cpu_suspend(am33xx_do_wfi_sram, wfi_flags);
148 static int __init am43xx_map_gic(void)
150         gic_dist_base = ioremap(AM43XX_GIC_DIST_BASE, SZ_4K);
152         if (!gic_dist_base)
153                 return -ENOMEM;
155         return 0;
158 #ifdef CONFIG_SUSPEND
160 static int rtc_only_idle;
161 static int retrigger_irq;
163 struct wkup_m3_wakeup_src rtc_wake_src(void)
165         u32 i;
167         i = __raw_readl(pm_ops->get_rtc_base_addr() + 0x44) & 0x40;
169         if (i) {
170                 retrigger_irq = rtc_alarm_wakeup.irq_nr;
171                 return rtc_alarm_wakeup;
172         }
174         retrigger_irq = rtc_ext_wakeup.irq_nr;
176         return rtc_ext_wakeup;
179 int am33xx_rtc_only_idle(unsigned long wfi_flags)
181         rtc_power_off_program(omap_rtc);
182         am33xx_do_wfi_sram(wfi_flags);
183         return 0;
186 static int am33xx_pm_suspend(suspend_state_t suspend_state)
188         int i, ret = 0;
190         if (suspend_state == PM_SUSPEND_MEM &&
191             pm_ops->check_off_mode_enable()) {
192                 pm_ops->prepare_rtc_suspend();
193                 pm_ops->save_context();
194                 suspend_wfi_flags |= WFI_FLAG_RTC_ONLY;
195                 clk_save_context();
196                 ret = pm_ops->soc_suspend(suspend_state, am33xx_rtc_only_idle,
197                                           suspend_wfi_flags);
199                 suspend_wfi_flags &= ~WFI_FLAG_RTC_ONLY;
201                 if (!ret) {
202                         clk_restore_context();
203                         pm_ops->restore_context();
204                         m3_ipc->ops->set_rtc_only(m3_ipc);
205                         am33xx_push_sram_idle();
206                 }
207         } else {
208                 ret = pm_ops->soc_suspend(suspend_state, am33xx_do_wfi_sram,
209                                           suspend_wfi_flags);
210         }
212         if (ret) {
213                 dev_err(pm33xx_dev, "PM: Kernel suspend failure\n");
214         } else {
215                 i = m3_ipc->ops->request_pm_status(m3_ipc);
217                 switch (i) {
218                 case 0:
219                         dev_info(pm33xx_dev,
220                                  "PM: Successfully put all powerdomains to target state\n");
221                         break;
222                 case 1:
223                         dev_err(pm33xx_dev,
224                                 "PM: Could not transition all powerdomains to target state\n");
225                         ret = -1;
226                         break;
227                 default:
228                         dev_err(pm33xx_dev,
229                                 "PM: CM3 returned unknown result = %d\n", i);
230                         ret = -1;
231                 }
233                 /* print the wakeup reason */
234                 if (rtc_only_idle) {
235                         wakeup_src = rtc_wake_src();
236                         pr_info("PM: Wakeup source %s\n", wakeup_src.src);
237                 } else {
238                         pr_info("PM: Wakeup source %s\n",
239                                 m3_ipc->ops->request_wake_src(m3_ipc));
240                 }
241         }
243         if (suspend_state == PM_SUSPEND_MEM && pm_ops->check_off_mode_enable())
244                 pm_ops->prepare_rtc_resume();
246         return ret;
249 static int am33xx_pm_enter(suspend_state_t suspend_state)
251         int ret = 0;
253         switch (suspend_state) {
254         case PM_SUSPEND_MEM:
255         case PM_SUSPEND_STANDBY:
256                 ret = am33xx_pm_suspend(suspend_state);
257                 break;
258         default:
259                 ret = -EINVAL;
260         }
262         return ret;
265 static int am33xx_pm_begin(suspend_state_t state)
267         int ret = -EINVAL;
269         if (state == PM_SUSPEND_MEM && pm_ops->check_off_mode_enable()) {
270                 nvmem_device_write(omap_rtc->nvmem, RTC_SCRATCH_MAGIC_REG * 4,
271                                    4, (void *)&rtc_magic_val);
272                 rtc_only_idle = 1;
273         } else {
274                 rtc_only_idle = 0;
275         }
277         cpu_idle_poll_ctrl(true);
279         switch (state) {
280         case PM_SUSPEND_MEM:
281                 ret = m3_ipc->ops->prepare_low_power(m3_ipc, WKUP_M3_DEEPSLEEP);
282                 break;
283         case PM_SUSPEND_STANDBY:
284                 ret = m3_ipc->ops->prepare_low_power(m3_ipc, WKUP_M3_STANDBY);
285                 break;
286         }
288         return ret;
291 static void am33xx_pm_end(void)
293         u32 val = 0;
295         m3_ipc->ops->finish_low_power(m3_ipc);
296         if (rtc_only_idle) {
297                 if (retrigger_irq)
298                         /*
299                          * 32 bits of Interrupt Set-Pending correspond to 32
300                          * 32 interupts. Compute the bit offset of the
301                          * Interrupt and set that particular bit
302                          * Compute the register offset by dividing interrupt
303                          * number by 32 and mutiplying by 4
304                          */
305                         writel_relaxed(1 << (retrigger_irq & 31),
306                                        gic_dist_base + GIC_INT_SET_PENDING_BASE
307                                        + retrigger_irq / 32 * 4);
308                         nvmem_device_write(omap_rtc->nvmem,
309                                            RTC_SCRATCH_MAGIC_REG * 4,
310                                            4, (void *)&val);
311         }
313         rtc_only_idle = 0;
315         cpu_idle_poll_ctrl(false);
318 static int am33xx_pm_valid(suspend_state_t state)
320         switch (state) {
321         case PM_SUSPEND_STANDBY:
322         case PM_SUSPEND_MEM:
323                 return 1;
324         default:
325                 return 0;
326         }
329 static const struct platform_suspend_ops am33xx_pm_ops = {
330         .begin          = am33xx_pm_begin,
331         .end            = am33xx_pm_end,
332         .enter          = am33xx_pm_enter,
333         .valid          = am33xx_pm_valid,
334 };
335 #endif /* CONFIG_SUSPEND */
337 static void am33xx_pm_set_ipc_ops(void)
339         u32 resume_address;
340         int temp;
342         temp = ti_emif_get_mem_type();
343         if (temp < 0) {
344                 dev_err(pm33xx_dev, "PM: Cannot determine memory type, no PM available\n");
345                 return;
346         }
347         m3_ipc->ops->set_mem_type(m3_ipc, temp);
349         /* Physical resume address to be used by ROM code */
350         resume_address = am33xx_do_wfi_sram_phys +
351                          *pm_sram->resume_offset + 0x4;
353         m3_ipc->ops->set_resume_address(m3_ipc, (void *)resume_address);
356 static void am33xx_pm_free_sram(void)
358         gen_pool_free(sram_pool, ocmcram_location, *pm_sram->do_wfi_sz);
359         gen_pool_free(sram_pool_data, ocmcram_location_data,
360                       sizeof(struct am33xx_pm_ro_sram_data));
363 /*
364  * Push the minimal suspend-resume code to SRAM
365  */
366 static int am33xx_pm_alloc_sram(void)
368         struct device_node *np;
369         int ret = 0;
371         np = of_find_compatible_node(NULL, NULL, "ti,omap3-mpu");
372         if (!np) {
373                 np = of_find_compatible_node(NULL, NULL, "ti,omap4-mpu");
374                 if (!np) {
375                         dev_err(pm33xx_dev, "PM: %s: Unable to find device node for mpu\n",
376                                 __func__);
377                         return -ENODEV;
378                 }
379         }
381         sram_pool = of_gen_pool_get(np, "pm-sram", 0);
382         if (!sram_pool) {
383                 dev_err(pm33xx_dev, "PM: %s: Unable to get sram pool for ocmcram\n",
384                         __func__);
385                 ret = -ENODEV;
386                 goto mpu_put_node;
387         }
389         sram_pool_data = of_gen_pool_get(np, "pm-sram", 1);
390         if (!sram_pool_data) {
391                 dev_err(pm33xx_dev, "PM: %s: Unable to get sram data pool for ocmcram\n",
392                         __func__);
393                 ret = -ENODEV;
394                 goto mpu_put_node;
395         }
397         ocmcram_location = gen_pool_alloc(sram_pool, *pm_sram->do_wfi_sz);
398         if (!ocmcram_location) {
399                 dev_err(pm33xx_dev, "PM: %s: Unable to allocate memory from ocmcram\n",
400                         __func__);
401                 ret = -ENOMEM;
402                 goto mpu_put_node;
403         }
405         ocmcram_location_data = gen_pool_alloc(sram_pool_data,
406                                                sizeof(struct emif_regs_amx3));
407         if (!ocmcram_location_data) {
408                 dev_err(pm33xx_dev, "PM: Unable to allocate memory from ocmcram\n");
409                 gen_pool_free(sram_pool, ocmcram_location, *pm_sram->do_wfi_sz);
410                 ret = -ENOMEM;
411         }
413 mpu_put_node:
414         of_node_put(np);
415         return ret;
418 static int am33xx_pm_rtc_setup(void)
420         struct device_node *np;
421         unsigned long val = 0;
423         np = of_find_node_by_name(NULL, "rtc");
425         if (of_device_is_available(np)) {
426                 omap_rtc = rtc_class_open("rtc0");
427                 if (!omap_rtc) {
428                         pr_warn("PM: rtc0 not available");
429                         return -EPROBE_DEFER;
430                 }
432                 nvmem_device_read(omap_rtc->nvmem, RTC_SCRATCH_MAGIC_REG * 4,
433                                   4, (void *)&rtc_magic_val);
434                 if ((rtc_magic_val & 0xffff) != RTC_REG_BOOT_MAGIC)
435                         pr_warn("PM: bootloader does not support rtc-only!\n");
437                 nvmem_device_write(omap_rtc->nvmem, RTC_SCRATCH_MAGIC_REG * 4,
438                                    4, (void *)&val);
439                 val = pm_sram->resume_address;
440                 nvmem_device_write(omap_rtc->nvmem, RTC_SCRATCH_RESUME_REG * 4,
441                                    4, (void *)&val);
442         } else {
443                 pr_warn("PM: no-rtc available, rtc-only mode disabled.\n");
444         }
446         return 0;
449 static int am33xx_pm_probe(struct platform_device *pdev)
451         struct device *dev = &pdev->dev;
452         int ret;
454         if (!of_machine_is_compatible("ti,am33xx") &&
455             !of_machine_is_compatible("ti,am43"))
456                 return -ENODEV;
458         pm_ops = dev->platform_data;
459         if (!pm_ops) {
460                 dev_err(dev, "PM: Cannot get core PM ops!\n");
461                 return -ENODEV;
462         }
464         ret = am43xx_map_gic();
465         if (ret) {
466                 pr_err("PM: Could not ioremap GIC base\n");
467                 return ret;
468         }
470         pm_sram = pm_ops->get_sram_addrs();
471         if (!pm_sram) {
472                 dev_err(dev, "PM: Cannot get PM asm function addresses!!\n");
473                 return -ENODEV;
474         }
476         m3_ipc = wkup_m3_ipc_get();
477         if (!m3_ipc) {
478                 pr_err("PM: Cannot get wkup_m3_ipc handle\n");
479                 return -EPROBE_DEFER;
480         }
482         pm33xx_dev = dev;
484         ret = am33xx_pm_alloc_sram();
485         if (ret)
486                 return ret;
488         ret = am33xx_pm_rtc_setup();
489         if (ret)
490                 goto err_free_sram;
492         ret = am33xx_push_sram_idle();
493         if (ret)
494                 goto err_free_sram;
496         am33xx_pm_set_ipc_ops();
498 #ifdef CONFIG_SUSPEND
499         suspend_set_ops(&am33xx_pm_ops);
501         /*
502          * For a system suspend we must flush the caches, we want
503          * the DDR in self-refresh, we want to save the context
504          * of the EMIF, and we want the wkup_m3 to handle low-power
505          * transition.
506          */
507         suspend_wfi_flags |= WFI_FLAG_FLUSH_CACHE;
508         suspend_wfi_flags |= WFI_FLAG_SELF_REFRESH;
509         suspend_wfi_flags |= WFI_FLAG_SAVE_EMIF;
510         suspend_wfi_flags |= WFI_FLAG_WAKE_M3;
511 #endif /* CONFIG_SUSPEND */
513         ret = pm_ops->init(am33xx_do_sram_idle);
514         if (ret) {
515                 dev_err(dev, "Unable to call core pm init!\n");
516                 ret = -ENODEV;
517                 goto err_put_wkup_m3_ipc;
518         }
520         return 0;
522 err_put_wkup_m3_ipc:
523         wkup_m3_ipc_put(m3_ipc);
524 err_free_sram:
525         am33xx_pm_free_sram();
526         pm33xx_dev = NULL;
527         return ret;
530 static int am33xx_pm_remove(struct platform_device *pdev)
532         if (pm_ops->deinit)
533                 pm_ops->deinit();
534         suspend_set_ops(NULL);
535         wkup_m3_ipc_put(m3_ipc);
536         am33xx_pm_free_sram();
537         return 0;
540 static struct platform_driver am33xx_pm_driver = {
541         .driver = {
542                 .name   = "pm33xx",
543         },
544         .probe = am33xx_pm_probe,
545         .remove = am33xx_pm_remove,
546 };
547 module_platform_driver(am33xx_pm_driver);
549 MODULE_ALIAS("platform:pm33xx");
550 MODULE_LICENSE("GPL v2");
551 MODULE_DESCRIPTION("am33xx power management driver");