b16fed8911be696ef4609183c5e7512a4b12620b
[rpmsg/hwspinlock.git] / arch / arm / mach-omap2 / pm33xx-core.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * AM33XX Arch Power Management Routines
4  *
5  * Copyright (C) 2016-2018 Texas Instruments Incorporated - http://www.ti.com/
6  *      Dave Gerlach
7  */
9 #include <linux/cpuidle.h>
10 #include <linux/platform_data/pm33xx.h>
11 #include <asm/cpuidle.h>
12 #include <asm/smp_scu.h>
13 #include <asm/suspend.h>
14 #include <linux/errno.h>
15 #include <linux/clk.h>
16 #include <linux/platform_data/gpio-omap.h>
17 #include <linux/pinctrl/pinmux.h>
18 #include <linux/wkup_m3_ipc.h>
19 #include <linux/of.h>
20 #include <linux/rtc.h>
22 #include "cm33xx.h"
23 #include "common.h"
24 #include "control.h"
25 #include "clockdomain.h"
26 #include "iomap.h"
27 #include "omap_hwmod.h"
28 #include "pm.h"
29 #include "powerdomain.h"
30 #include "prm33xx.h"
31 #include "soc.h"
32 #include "sram.h"
34 static struct powerdomain *cefuse_pwrdm, *gfx_pwrdm, *per_pwrdm, *mpu_pwrdm;
35 static struct clockdomain *gfx_l4ls_clkdm;
36 static void __iomem *scu_base;
37 static struct omap_hwmod *rtc_oh;
39 static int (*idle_fn)(u32 wfi_flags);
41 struct amx3_idle_state {
42         int wfi_flags;
43 };
45 static struct amx3_idle_state *idle_states;
47 static int __init am43xx_map_scu(void)
48 {
49         scu_base = ioremap(scu_a9_get_base(), SZ_256);
51         if (!scu_base)
52                 return -ENOMEM;
54         return 0;
55 }
57 static int am33xx_check_off_mode_enable(void)
58 {
59         if (enable_off_mode)
60                 pr_warn("WARNING: This platform does not support off-mode, entering DeepSleep suspend.\n");
62         /* off mode not supported on am335x so return 0 always */
63         return 0;
64 }
66 static int am43xx_check_off_mode_enable(void)
67 {
68         /*
69          * Check for am437x-sk-evm which due to HW design cannot support
70          * this mode reliably.
71          */
72         if (of_machine_is_compatible("ti,am437x-sk-evm") && enable_off_mode) {
73                 pr_warn("WARNING: This platform does not support off-mode, entering DeepSleep suspend.\n");
74                 return 0;
75         }
77         return enable_off_mode;
78 }
80 static int amx3_common_init(void)
81 {
82         gfx_pwrdm = pwrdm_lookup("gfx_pwrdm");
83         per_pwrdm = pwrdm_lookup("per_pwrdm");
84         mpu_pwrdm = pwrdm_lookup("mpu_pwrdm");
86         if ((!gfx_pwrdm) || (!per_pwrdm) || (!mpu_pwrdm))
87                 return -ENODEV;
89         (void)clkdm_for_each(omap_pm_clkdms_setup, NULL);
91         /* CEFUSE domain can be turned off post bootup */
92         cefuse_pwrdm = pwrdm_lookup("cefuse_pwrdm");
93         if (cefuse_pwrdm)
94                 omap_set_pwrdm_state(cefuse_pwrdm, PWRDM_POWER_OFF);
95         else
96                 pr_err("PM: Failed to get cefuse_pwrdm\n");
98         return 0;
99 }
101 static int am33xx_suspend_init(void)
103         int ret;
105         gfx_l4ls_clkdm = clkdm_lookup("gfx_l4ls_gfx_clkdm");
107         if (!gfx_l4ls_clkdm) {
108                 pr_err("PM: Cannot lookup gfx_l4ls_clkdm clockdomains\n");
109                 return -ENODEV;
110         }
112         ret = amx3_common_init();
114         return ret;
117 static int am43xx_suspend_init(void)
119         int ret = 0;
121         ret = am43xx_map_scu();
122         if (ret) {
123                 pr_err("PM: Could not ioremap SCU\n");
124                 return ret;
125         }
127         ret = amx3_common_init();
129         return ret;
132 static void amx3_pre_suspend_common(void)
134         omap_set_pwrdm_state(gfx_pwrdm, PWRDM_POWER_OFF);
137 static void amx3_post_suspend_common(void)
139         int status;
140         /*
141          * Because gfx_pwrdm is the only one under MPU control,
142          * comment on transition status
143          */
144         status = pwrdm_read_pwrst(gfx_pwrdm);
145         if (status != PWRDM_POWER_OFF)
146                 pr_err("PM: GFX domain did not transition: %x\n", status);
149 static int am33xx_suspend(unsigned int state, int (*fn)(unsigned long),
150                           unsigned long args)
152         int ret = 0;
154         amx3_pre_suspend_common();
155         ret = cpu_suspend(args, fn);
156         amx3_post_suspend_common();
158         /*
159          * BUG: GFX_L4LS clock domain needs to be woken up to
160          * ensure thet L4LS clock domain does not get stuck in
161          * transition. If that happens L3 module does not get
162          * disabled, thereby leading to PER power domain
163          * transition failing
164          */
166         clkdm_wakeup(gfx_l4ls_clkdm);
167         clkdm_sleep(gfx_l4ls_clkdm);
169         return ret;
172 static int am43xx_suspend(unsigned int state, int (*fn)(unsigned long),
173                           unsigned long args)
175         int ret = 0;
177         amx3_pre_suspend_common();
178         scu_power_mode(scu_base, SCU_PM_POWEROFF);
179         ret = cpu_suspend(args, fn);
180         scu_power_mode(scu_base, SCU_PM_NORMAL);
182         if (!am43xx_check_off_mode_enable())
183                 amx3_post_suspend_common();
185         return ret;
188 static struct am33xx_pm_sram_addr *amx3_get_sram_addrs(void)
190         if (soc_is_am33xx())
191                 return &am33xx_pm_sram;
192         else if (soc_is_am437x())
193                 return &am43xx_pm_sram;
194         else
195                 return NULL;
198 void __iomem *am43xx_get_rtc_base_addr(void)
200         rtc_oh = omap_hwmod_lookup("rtc");
202         return omap_hwmod_get_mpu_rt_va(rtc_oh);
205 static void am43xx_save_context(void)
209 static void am33xx_save_context(void)
211         omap_intc_save_context();
214 static void am33xx_restore_context(void)
216         omap_intc_restore_context();
219 static void am43xx_restore_context(void)
221         /*
222          * HACK: restore dpll_per_clkdcoldo register contents, to avoid
223          * breaking suspend-resume
224          */
225         writel_relaxed(0x0, AM33XX_L4_WK_IO_ADDRESS(0x44df2e14));
228 static void am43xx_prepare_rtc_suspend(void)
230         omap_hwmod_enable(rtc_oh);
233 static void am43xx_prepare_rtc_resume(void)
235         omap_hwmod_idle(rtc_oh);
238 static struct am33xx_pm_platform_data am33xx_ops = {
239         .init = am33xx_suspend_init,
240         .soc_suspend = am33xx_suspend,
241         .get_sram_addrs = amx3_get_sram_addrs,
242         .save_context = am33xx_save_context,
243         .restore_context = am33xx_restore_context,
244         .prepare_rtc_suspend = am43xx_prepare_rtc_suspend,
245         .prepare_rtc_resume = am43xx_prepare_rtc_resume,
246         .check_off_mode_enable = am33xx_check_off_mode_enable,
247         .get_rtc_base_addr = am43xx_get_rtc_base_addr,
248 };
250 static struct am33xx_pm_platform_data am43xx_ops = {
251         .init = am43xx_suspend_init,
252         .soc_suspend = am43xx_suspend,
253         .get_sram_addrs = amx3_get_sram_addrs,
254         .save_context = am43xx_save_context,
255         .restore_context = am43xx_restore_context,
256         .prepare_rtc_suspend = am43xx_prepare_rtc_suspend,
257         .prepare_rtc_resume = am43xx_prepare_rtc_resume,
258         .check_off_mode_enable = am43xx_check_off_mode_enable,
259         .get_rtc_base_addr = am43xx_get_rtc_base_addr,
260 };
262 static struct am33xx_pm_platform_data *am33xx_pm_get_pdata(void)
264         if (soc_is_am33xx())
265                 return &am33xx_ops;
266         else if (soc_is_am437x())
267                 return &am43xx_ops;
268         else
269                 return NULL;
272 int __init amx3_common_pm_init(void)
274         struct am33xx_pm_platform_data *pdata;
275         struct platform_device_info devinfo;
277         pdata = am33xx_pm_get_pdata();
279         memset(&devinfo, 0, sizeof(devinfo));
280         devinfo.name = "pm33xx";
281         devinfo.data = pdata;
282         devinfo.size_data = sizeof(*pdata);
283         devinfo.id = -1;
284         platform_device_register_full(&devinfo);
286         return 0;
289 static int __init amx3_idle_init(struct device_node *cpu_node, int cpu)
291         struct device_node *state_node;
292         struct amx3_idle_state states[CPUIDLE_STATE_MAX];
293         int i;
294         int state_count = 1;
296         for (i = 0; ; i++) {
297                 state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i);
298                 if (!state_node)
299                         break;
301                 if (!of_device_is_available(state_node))
302                         continue;
304                 if (i == CPUIDLE_STATE_MAX) {
305                         pr_warn("%s: cpuidle states reached max possible\n",
306                                 __func__);
307                         break;
308                 }
310                 states[state_count].wfi_flags = 0;
312                 if (of_property_read_bool(state_node, "ti,idle-wkup-m3"))
313                         states[state_count].wfi_flags |= WFI_FLAG_WAKE_M3 |
314                                                          WFI_FLAG_FLUSH_CACHE;
316                 state_count++;
317         }
319         idle_states = kcalloc(state_count, sizeof(*idle_states), GFP_KERNEL);
320         if (!idle_states)
321                 return -ENOMEM;
323         for (i = 1; i < state_count; i++)
324                 idle_states[i].wfi_flags = states[i].wfi_flags;
326         return 0;
329 static int amx3_idle_enter(unsigned long index)
331         struct amx3_idle_state *idle_state = &idle_states[index];
333         if (!idle_state)
334                 return -EINVAL;
336         if (idle_fn)
337                 idle_fn(idle_state->wfi_flags);
339         return 0;
342 static struct cpuidle_ops amx3_cpuidle_ops __initdata = {
343         .init = amx3_idle_init,
344         .suspend = amx3_idle_enter,
345 };
347 CPUIDLE_METHOD_OF_DECLARE(pm33xx_idle, "ti,am3352", &amx3_cpuidle_ops);
348 CPUIDLE_METHOD_OF_DECLARE(pm43xx_idle, "ti,am4372", &amx3_cpuidle_ops);