diff options
author | Shawn Guo <shawn.guo@freescale.com> | 2014-05-20 02:55:15 -0400 |
---|---|---|
committer | Shawn Guo <shawn.guo@freescale.com> | 2014-07-18 04:10:09 -0400 |
commit | 36b66c3fc20ad9a50ae7f19b3c807c68259753df (patch) | |
tree | eb47f70f7ca833acf1fa73d2b1b20c588fdb1a4e /arch/arm | |
parent | 4ef5e3870113c5caab22d4363d882b372f2c6b57 (diff) |
ARM: imx5: use dynamic mapping for Cortex and GPC block
The imx5 pm code uses static mapping to access Cortex and GPC registers.
The patch create struct imx5_pm_data to encode physical address of
Cortex and GPC block, and create dynamic mapping for them at run-time.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-imx/common.h | 6 | ||||
-rw-r--r-- | arch/arm/mach-imx/mm-imx5.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-imx/pm-imx5.c | 84 |
3 files changed, 60 insertions, 34 deletions
diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index 8aa198c9b1d5..1156bf6cbeb5 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h | |||
@@ -142,10 +142,12 @@ void imx6sl_pm_init(void); | |||
142 | void imx6q_pm_set_ccm_base(void __iomem *base); | 142 | void imx6q_pm_set_ccm_base(void __iomem *base); |
143 | 143 | ||
144 | #ifdef CONFIG_PM | 144 | #ifdef CONFIG_PM |
145 | void imx5_pm_init(void); | 145 | void imx51_pm_init(void); |
146 | void imx53_pm_init(void); | ||
146 | void imx5_pm_set_ccm_base(void __iomem *base); | 147 | void imx5_pm_set_ccm_base(void __iomem *base); |
147 | #else | 148 | #else |
148 | static inline void imx5_pm_init(void) {} | 149 | static inline void imx51_pm_init(void) {} |
150 | static inline void imx53_pm_init(void) {} | ||
149 | static inline void imx5_pm_set_ccm_base(void __iomem *base) {} | 151 | static inline void imx5_pm_set_ccm_base(void __iomem *base) {} |
150 | #endif | 152 | #endif |
151 | 153 | ||
diff --git a/arch/arm/mach-imx/mm-imx5.c b/arch/arm/mach-imx/mm-imx5.c index 771ab3645621..9e43e879bac5 100644 --- a/arch/arm/mach-imx/mm-imx5.c +++ b/arch/arm/mach-imx/mm-imx5.c | |||
@@ -96,10 +96,10 @@ void __init imx53_init_early(void) | |||
96 | void __init imx51_init_late(void) | 96 | void __init imx51_init_late(void) |
97 | { | 97 | { |
98 | mx51_neon_fixup(); | 98 | mx51_neon_fixup(); |
99 | imx5_pm_init(); | 99 | imx51_pm_init(); |
100 | } | 100 | } |
101 | 101 | ||
102 | void __init imx53_init_late(void) | 102 | void __init imx53_init_late(void) |
103 | { | 103 | { |
104 | imx5_pm_init(); | 104 | imx53_pm_init(); |
105 | } | 105 | } |
diff --git a/arch/arm/mach-imx/pm-imx5.c b/arch/arm/mach-imx/pm-imx5.c index 3544c2524617..f1f80ab73e69 100644 --- a/arch/arm/mach-imx/pm-imx5.c +++ b/arch/arm/mach-imx/pm-imx5.c | |||
@@ -28,21 +28,14 @@ | |||
28 | #define MXC_CCM_CLPCR_VSTBY (0x1 << 8) | 28 | #define MXC_CCM_CLPCR_VSTBY (0x1 << 8) |
29 | #define MXC_CCM_CLPCR_SBYOS (0x1 << 6) | 29 | #define MXC_CCM_CLPCR_SBYOS (0x1 << 6) |
30 | 30 | ||
31 | #define MX51_CORTEXA8_BASE MX51_IO_ADDRESS(MX51_ARM_BASE_ADDR) | 31 | #define MXC_CORTEXA8_PLAT_LPC 0xc |
32 | #define MXC_CORTEXA8_PLAT_LPC (MX51_CORTEXA8_BASE + 0xc) | ||
33 | #define MXC_CORTEXA8_PLAT_LPC_DSM (1 << 0) | 32 | #define MXC_CORTEXA8_PLAT_LPC_DSM (1 << 0) |
34 | #define MXC_CORTEXA8_PLAT_LPC_DBG_DSM (1 << 1) | 33 | #define MXC_CORTEXA8_PLAT_LPC_DBG_DSM (1 << 1) |
35 | 34 | ||
36 | #define MX51_GPC_BASE MX51_IO_ADDRESS(MX51_GPC_BASE_ADDR) | 35 | #define MXC_SRPG_NEON_SRPGCR 0x280 |
37 | #define MXC_SRPG_NEON_BASE (MX51_GPC_BASE + 0x280) | 36 | #define MXC_SRPG_ARM_SRPGCR 0x2a0 |
38 | #define MXC_SRPG_ARM_BASE (MX51_GPC_BASE + 0x2a0) | 37 | #define MXC_SRPG_EMPGC0_SRPGCR 0x2c0 |
39 | #define MXC_SRPG_EMPGC0_BASE (MX51_GPC_BASE + 0x2c0) | 38 | #define MXC_SRPG_EMPGC1_SRPGCR 0x2d0 |
40 | #define MXC_SRPG_EMPGC1_BASE (MX51_GPC_BASE + 0x2d0) | ||
41 | |||
42 | #define MXC_SRPG_NEON_SRPGCR (MXC_SRPG_NEON_BASE + 0x0) | ||
43 | #define MXC_SRPG_ARM_SRPGCR (MXC_SRPG_ARM_BASE + 0x0) | ||
44 | #define MXC_SRPG_EMPGC0_SRPGCR (MXC_SRPG_EMPGC0_BASE + 0x0) | ||
45 | #define MXC_SRPG_EMPGC1_SRPGCR (MXC_SRPG_EMPGC1_BASE + 0x0) | ||
46 | 39 | ||
47 | #define MXC_SRPGCR_PCR 1 | 40 | #define MXC_SRPGCR_PCR 1 |
48 | 41 | ||
@@ -56,7 +49,24 @@ | |||
56 | */ | 49 | */ |
57 | #define IMX5_DEFAULT_CPU_IDLE_STATE WAIT_UNCLOCKED_POWER_OFF | 50 | #define IMX5_DEFAULT_CPU_IDLE_STATE WAIT_UNCLOCKED_POWER_OFF |
58 | 51 | ||
52 | struct imx5_pm_data { | ||
53 | phys_addr_t cortex_addr; | ||
54 | phys_addr_t gpc_addr; | ||
55 | }; | ||
56 | |||
57 | static const struct imx5_pm_data imx51_pm_data __initconst = { | ||
58 | .cortex_addr = 0x83fa0000, | ||
59 | .gpc_addr = 0x73fd8000, | ||
60 | }; | ||
61 | |||
62 | static const struct imx5_pm_data imx53_pm_data __initconst = { | ||
63 | .cortex_addr = 0x63fa0000, | ||
64 | .gpc_addr = 0x53fd8000, | ||
65 | }; | ||
66 | |||
59 | static void __iomem *ccm_base; | 67 | static void __iomem *ccm_base; |
68 | static void __iomem *cortex_base; | ||
69 | static void __iomem *gpc_base; | ||
60 | 70 | ||
61 | void __init imx5_pm_set_ccm_base(void __iomem *base) | 71 | void __init imx5_pm_set_ccm_base(void __iomem *base) |
62 | { | 72 | { |
@@ -74,13 +84,16 @@ static void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode) | |||
74 | int stop_mode = 0; | 84 | int stop_mode = 0; |
75 | 85 | ||
76 | /* always allow platform to issue a deep sleep mode request */ | 86 | /* always allow platform to issue a deep sleep mode request */ |
77 | plat_lpc = __raw_readl(MXC_CORTEXA8_PLAT_LPC) & | 87 | plat_lpc = __raw_readl(cortex_base + MXC_CORTEXA8_PLAT_LPC) & |
78 | ~(MXC_CORTEXA8_PLAT_LPC_DSM); | 88 | ~(MXC_CORTEXA8_PLAT_LPC_DSM); |
79 | ccm_clpcr = __raw_readl(ccm_base + MXC_CCM_CLPCR) & | 89 | ccm_clpcr = __raw_readl(ccm_base + MXC_CCM_CLPCR) & |
80 | ~(MXC_CCM_CLPCR_LPM_MASK); | 90 | ~(MXC_CCM_CLPCR_LPM_MASK); |
81 | arm_srpgcr = __raw_readl(MXC_SRPG_ARM_SRPGCR) & ~(MXC_SRPGCR_PCR); | 91 | arm_srpgcr = __raw_readl(gpc_base + MXC_SRPG_ARM_SRPGCR) & |
82 | empgc0 = __raw_readl(MXC_SRPG_EMPGC0_SRPGCR) & ~(MXC_SRPGCR_PCR); | 92 | ~(MXC_SRPGCR_PCR); |
83 | empgc1 = __raw_readl(MXC_SRPG_EMPGC1_SRPGCR) & ~(MXC_SRPGCR_PCR); | 93 | empgc0 = __raw_readl(gpc_base + MXC_SRPG_EMPGC0_SRPGCR) & |
94 | ~(MXC_SRPGCR_PCR); | ||
95 | empgc1 = __raw_readl(gpc_base + MXC_SRPG_EMPGC1_SRPGCR) & | ||
96 | ~(MXC_SRPGCR_PCR); | ||
84 | 97 | ||
85 | switch (mode) { | 98 | switch (mode) { |
86 | case WAIT_CLOCKED: | 99 | case WAIT_CLOCKED: |
@@ -114,17 +127,17 @@ static void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode) | |||
114 | return; | 127 | return; |
115 | } | 128 | } |
116 | 129 | ||
117 | __raw_writel(plat_lpc, MXC_CORTEXA8_PLAT_LPC); | 130 | __raw_writel(plat_lpc, cortex_base + MXC_CORTEXA8_PLAT_LPC); |
118 | __raw_writel(ccm_clpcr, ccm_base + MXC_CCM_CLPCR); | 131 | __raw_writel(ccm_clpcr, ccm_base + MXC_CCM_CLPCR); |
119 | __raw_writel(arm_srpgcr, MXC_SRPG_ARM_SRPGCR); | 132 | __raw_writel(arm_srpgcr, gpc_base + MXC_SRPG_ARM_SRPGCR); |
120 | __raw_writel(arm_srpgcr, MXC_SRPG_NEON_SRPGCR); | 133 | __raw_writel(arm_srpgcr, gpc_base + MXC_SRPG_NEON_SRPGCR); |
121 | 134 | ||
122 | if (stop_mode) { | 135 | if (stop_mode) { |
123 | empgc0 |= MXC_SRPGCR_PCR; | 136 | empgc0 |= MXC_SRPGCR_PCR; |
124 | empgc1 |= MXC_SRPGCR_PCR; | 137 | empgc1 |= MXC_SRPGCR_PCR; |
125 | 138 | ||
126 | __raw_writel(empgc0, MXC_SRPG_EMPGC0_SRPGCR); | 139 | __raw_writel(empgc0, gpc_base + MXC_SRPG_EMPGC0_SRPGCR); |
127 | __raw_writel(empgc1, MXC_SRPG_EMPGC1_SRPGCR); | 140 | __raw_writel(empgc1, gpc_base + MXC_SRPG_EMPGC1_SRPGCR); |
128 | } | 141 | } |
129 | } | 142 | } |
130 | 143 | ||
@@ -146,8 +159,8 @@ static int mx5_suspend_enter(suspend_state_t state) | |||
146 | flush_cache_all(); | 159 | flush_cache_all(); |
147 | 160 | ||
148 | /*clear the EMPGC0/1 bits */ | 161 | /*clear the EMPGC0/1 bits */ |
149 | __raw_writel(0, MXC_SRPG_EMPGC0_SRPGCR); | 162 | __raw_writel(0, gpc_base + MXC_SRPG_EMPGC0_SRPGCR); |
150 | __raw_writel(0, MXC_SRPG_EMPGC1_SRPGCR); | 163 | __raw_writel(0, gpc_base + MXC_SRPG_EMPGC1_SRPGCR); |
151 | } | 164 | } |
152 | cpu_do_idle(); | 165 | cpu_do_idle(); |
153 | 166 | ||
@@ -181,7 +194,7 @@ static void imx5_pm_idle(void) | |||
181 | imx5_cpu_do_idle(); | 194 | imx5_cpu_do_idle(); |
182 | } | 195 | } |
183 | 196 | ||
184 | static int __init imx5_pm_common_init(void) | 197 | static int __init imx5_pm_common_init(const struct imx5_pm_data *data) |
185 | { | 198 | { |
186 | int ret; | 199 | int ret; |
187 | struct clk *gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs"); | 200 | struct clk *gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs"); |
@@ -195,17 +208,28 @@ static int __init imx5_pm_common_init(void) | |||
195 | 208 | ||
196 | arm_pm_idle = imx5_pm_idle; | 209 | arm_pm_idle = imx5_pm_idle; |
197 | 210 | ||
198 | WARN_ON(!ccm_base); | 211 | cortex_base = ioremap(data->cortex_addr, SZ_16K); |
212 | gpc_base = ioremap(data->gpc_addr, SZ_16K); | ||
213 | WARN_ON(!ccm_base || !cortex_base || !gpc_base); | ||
199 | 214 | ||
200 | /* Set the registers to the default cpu idle state. */ | 215 | /* Set the registers to the default cpu idle state. */ |
201 | mx5_cpu_lp_set(IMX5_DEFAULT_CPU_IDLE_STATE); | 216 | mx5_cpu_lp_set(IMX5_DEFAULT_CPU_IDLE_STATE); |
202 | 217 | ||
203 | return imx5_cpuidle_init(); | 218 | ret = imx5_cpuidle_init(); |
219 | if (ret) | ||
220 | pr_warn("%s: cpuidle init failed %d\n", __func__, ret); | ||
221 | |||
222 | suspend_set_ops(&mx5_suspend_ops); | ||
223 | |||
224 | return 0; | ||
225 | } | ||
226 | |||
227 | void __init imx51_pm_init(void) | ||
228 | { | ||
229 | imx5_pm_common_init(&imx51_pm_data); | ||
204 | } | 230 | } |
205 | 231 | ||
206 | void __init imx5_pm_init(void) | 232 | void __init imx53_pm_init(void) |
207 | { | 233 | { |
208 | int ret = imx5_pm_common_init(); | 234 | imx5_pm_common_init(&imx53_pm_data); |
209 | if (!ret) | ||
210 | suspend_set_ops(&mx5_suspend_ops); | ||
211 | } | 235 | } |