diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-imx/mm-imx5.c | 21 | ||||
-rw-r--r-- | arch/arm/mach-imx/pm-imx5.c | 67 | ||||
-rw-r--r-- | arch/arm/plat-mxc/include/mach/common.h | 3 |
3 files changed, 44 insertions, 47 deletions
diff --git a/arch/arm/mach-imx/mm-imx5.c b/arch/arm/mach-imx/mm-imx5.c index feeee17da96b..d84421e1467d 100644 --- a/arch/arm/mach-imx/mm-imx5.c +++ b/arch/arm/mach-imx/mm-imx5.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/clk.h> | 16 | #include <linux/clk.h> |
17 | #include <linux/pinctrl/machine.h> | 17 | #include <linux/pinctrl/machine.h> |
18 | 18 | ||
19 | #include <asm/system_misc.h> | ||
20 | #include <asm/mach/map.h> | 19 | #include <asm/mach/map.h> |
21 | 20 | ||
22 | #include <mach/hardware.h> | 21 | #include <mach/hardware.h> |
@@ -24,24 +23,6 @@ | |||
24 | #include <mach/devices-common.h> | 23 | #include <mach/devices-common.h> |
25 | #include <mach/iomux-v3.h> | 24 | #include <mach/iomux-v3.h> |
26 | 25 | ||
27 | static struct clk *gpc_dvfs_clk; | ||
28 | |||
29 | static void imx5_idle(void) | ||
30 | { | ||
31 | /* gpc clock is needed for SRPG */ | ||
32 | if (gpc_dvfs_clk == NULL) { | ||
33 | gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs"); | ||
34 | if (IS_ERR(gpc_dvfs_clk)) | ||
35 | return; | ||
36 | clk_prepare(gpc_dvfs_clk); | ||
37 | } | ||
38 | clk_enable(gpc_dvfs_clk); | ||
39 | mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF); | ||
40 | if (!tzic_enable_wake()) | ||
41 | cpu_do_idle(); | ||
42 | clk_disable(gpc_dvfs_clk); | ||
43 | } | ||
44 | |||
45 | /* | 26 | /* |
46 | * Define the MX50 memory map. | 27 | * Define the MX50 memory map. |
47 | */ | 28 | */ |
@@ -105,7 +86,6 @@ void __init imx51_init_early(void) | |||
105 | mxc_set_cpu_type(MXC_CPU_MX51); | 86 | mxc_set_cpu_type(MXC_CPU_MX51); |
106 | mxc_iomux_v3_init(MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR)); | 87 | mxc_iomux_v3_init(MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR)); |
107 | mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG1_BASE_ADDR)); | 88 | mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG1_BASE_ADDR)); |
108 | arm_pm_idle = imx5_idle; | ||
109 | } | 89 | } |
110 | 90 | ||
111 | void __init imx53_init_early(void) | 91 | void __init imx53_init_early(void) |
@@ -241,4 +221,5 @@ void __init imx53_soc_init(void) | |||
241 | void __init imx51_init_late(void) | 221 | void __init imx51_init_late(void) |
242 | { | 222 | { |
243 | mx51_neon_fixup(); | 223 | mx51_neon_fixup(); |
224 | imx51_pm_init(); | ||
244 | } | 225 | } |
diff --git a/arch/arm/mach-imx/pm-imx5.c b/arch/arm/mach-imx/pm-imx5.c index e26a9cb05ed8..baf93214f899 100644 --- a/arch/arm/mach-imx/pm-imx5.c +++ b/arch/arm/mach-imx/pm-imx5.c | |||
@@ -13,18 +13,27 @@ | |||
13 | #include <linux/io.h> | 13 | #include <linux/io.h> |
14 | #include <linux/err.h> | 14 | #include <linux/err.h> |
15 | #include <asm/cacheflush.h> | 15 | #include <asm/cacheflush.h> |
16 | #include <asm/system_misc.h> | ||
16 | #include <asm/tlbflush.h> | 17 | #include <asm/tlbflush.h> |
17 | #include <mach/common.h> | 18 | #include <mach/common.h> |
18 | #include <mach/hardware.h> | 19 | #include <mach/hardware.h> |
19 | #include "crm-regs-imx5.h" | 20 | #include "crm-regs-imx5.h" |
20 | 21 | ||
21 | static struct clk *gpc_dvfs_clk; | 22 | /* |
23 | * The WAIT_UNCLOCKED_POWER_OFF state only requires <= 500ns to exit. | ||
24 | * This is also the lowest power state possible without affecting | ||
25 | * non-cpu parts of the system. For these reasons, imx5 should default | ||
26 | * to always using this state for cpu idling. The PM_SUSPEND_STANDBY also | ||
27 | * uses this state and needs to take no action when registers remain confgiured | ||
28 | * for this state. | ||
29 | */ | ||
30 | #define IMX5_DEFAULT_CPU_IDLE_STATE WAIT_UNCLOCKED_POWER_OFF | ||
22 | 31 | ||
23 | /* | 32 | /* |
24 | * set cpu low power mode before WFI instruction. This function is called | 33 | * set cpu low power mode before WFI instruction. This function is called |
25 | * mx5 because it can be used for mx50, mx51, and mx53. | 34 | * mx5 because it can be used for mx50, mx51, and mx53. |
26 | */ | 35 | */ |
27 | void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode) | 36 | static void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode) |
28 | { | 37 | { |
29 | u32 plat_lpc, arm_srpgcr, ccm_clpcr; | 38 | u32 plat_lpc, arm_srpgcr, ccm_clpcr; |
30 | u32 empgc0, empgc1; | 39 | u32 empgc0, empgc1; |
@@ -87,11 +96,6 @@ void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode) | |||
87 | } | 96 | } |
88 | } | 97 | } |
89 | 98 | ||
90 | static int mx5_suspend_prepare(void) | ||
91 | { | ||
92 | return clk_prepare_enable(gpc_dvfs_clk); | ||
93 | } | ||
94 | |||
95 | static int mx5_suspend_enter(suspend_state_t state) | 99 | static int mx5_suspend_enter(suspend_state_t state) |
96 | { | 100 | { |
97 | switch (state) { | 101 | switch (state) { |
@@ -99,7 +103,7 @@ static int mx5_suspend_enter(suspend_state_t state) | |||
99 | mx5_cpu_lp_set(STOP_POWER_OFF); | 103 | mx5_cpu_lp_set(STOP_POWER_OFF); |
100 | break; | 104 | break; |
101 | case PM_SUSPEND_STANDBY: | 105 | case PM_SUSPEND_STANDBY: |
102 | mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF); | 106 | /* DEFAULT_IDLE_STATE already configured */ |
103 | break; | 107 | break; |
104 | default: | 108 | default: |
105 | return -EINVAL; | 109 | return -EINVAL; |
@@ -114,12 +118,10 @@ static int mx5_suspend_enter(suspend_state_t state) | |||
114 | __raw_writel(0, MXC_SRPG_EMPGC1_SRPGCR); | 118 | __raw_writel(0, MXC_SRPG_EMPGC1_SRPGCR); |
115 | } | 119 | } |
116 | cpu_do_idle(); | 120 | cpu_do_idle(); |
117 | return 0; | ||
118 | } | ||
119 | 121 | ||
120 | static void mx5_suspend_finish(void) | 122 | /* return registers to default idle state */ |
121 | { | 123 | mx5_cpu_lp_set(IMX5_DEFAULT_CPU_IDLE_STATE); |
122 | clk_disable_unprepare(gpc_dvfs_clk); | 124 | return 0; |
123 | } | 125 | } |
124 | 126 | ||
125 | static int mx5_pm_valid(suspend_state_t state) | 127 | static int mx5_pm_valid(suspend_state_t state) |
@@ -129,25 +131,38 @@ static int mx5_pm_valid(suspend_state_t state) | |||
129 | 131 | ||
130 | static const struct platform_suspend_ops mx5_suspend_ops = { | 132 | static const struct platform_suspend_ops mx5_suspend_ops = { |
131 | .valid = mx5_pm_valid, | 133 | .valid = mx5_pm_valid, |
132 | .prepare = mx5_suspend_prepare, | ||
133 | .enter = mx5_suspend_enter, | 134 | .enter = mx5_suspend_enter, |
134 | .finish = mx5_suspend_finish, | ||
135 | }; | 135 | }; |
136 | 136 | ||
137 | static int __init mx5_pm_init(void) | 137 | static void imx5_pm_idle(void) |
138 | { | 138 | { |
139 | if (!cpu_is_mx51() && !cpu_is_mx53()) | 139 | if (likely(!tzic_enable_wake())) |
140 | return 0; | 140 | cpu_do_idle(); |
141 | } | ||
142 | |||
143 | static int __init imx5_pm_common_init(void) | ||
144 | { | ||
145 | int ret; | ||
146 | struct clk *gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs"); | ||
147 | |||
148 | if (IS_ERR(gpc_dvfs_clk)) | ||
149 | return PTR_ERR(gpc_dvfs_clk); | ||
141 | 150 | ||
142 | if (gpc_dvfs_clk == NULL) | 151 | ret = clk_prepare_enable(gpc_dvfs_clk); |
143 | gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs"); | 152 | if (ret) |
153 | return ret; | ||
144 | 154 | ||
145 | if (!IS_ERR(gpc_dvfs_clk)) { | 155 | arm_pm_idle = imx5_pm_idle; |
146 | if (cpu_is_mx51()) | 156 | |
147 | suspend_set_ops(&mx5_suspend_ops); | 157 | /* Set the registers to the default cpu idle state. */ |
148 | } else | 158 | mx5_cpu_lp_set(IMX5_DEFAULT_CPU_IDLE_STATE); |
149 | return -EPERM; | ||
150 | 159 | ||
151 | return 0; | 160 | return 0; |
152 | } | 161 | } |
153 | device_initcall(mx5_pm_init); | 162 | |
163 | void __init imx51_pm_init(void) | ||
164 | { | ||
165 | int ret = imx5_pm_common_init(); | ||
166 | if (!ret) | ||
167 | suspend_set_ops(&mx5_suspend_ops); | ||
168 | } | ||
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h index cf663d84e7c1..f65d068e1820 100644 --- a/arch/arm/plat-mxc/include/mach/common.h +++ b/arch/arm/plat-mxc/include/mach/common.h | |||
@@ -95,7 +95,6 @@ enum mx3_cpu_pwr_mode { | |||
95 | }; | 95 | }; |
96 | 96 | ||
97 | extern void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode); | 97 | extern void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode); |
98 | extern void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode); | ||
99 | extern void imx_print_silicon_rev(const char *cpu, int srev); | 98 | extern void imx_print_silicon_rev(const char *cpu, int srev); |
100 | 99 | ||
101 | void avic_handle_irq(struct pt_regs *); | 100 | void avic_handle_irq(struct pt_regs *); |
@@ -146,8 +145,10 @@ extern void imx6q_clock_map_io(void); | |||
146 | 145 | ||
147 | #ifdef CONFIG_PM | 146 | #ifdef CONFIG_PM |
148 | extern void imx6q_pm_init(void); | 147 | extern void imx6q_pm_init(void); |
148 | extern void imx51_pm_init(void); | ||
149 | #else | 149 | #else |
150 | static inline void imx6q_pm_init(void) {} | 150 | static inline void imx6q_pm_init(void) {} |
151 | static inline void imx51_pm_init(void) {} | ||
151 | #endif | 152 | #endif |
152 | 153 | ||
153 | #ifdef CONFIG_NEON | 154 | #ifdef CONFIG_NEON |