aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorShawn Guo <shawn.guo@freescale.com>2014-05-20 02:55:15 -0400
committerShawn Guo <shawn.guo@freescale.com>2014-07-18 04:10:09 -0400
commit36b66c3fc20ad9a50ae7f19b3c807c68259753df (patch)
treeeb47f70f7ca833acf1fa73d2b1b20c588fdb1a4e /arch/arm
parent4ef5e3870113c5caab22d4363d882b372f2c6b57 (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.h6
-rw-r--r--arch/arm/mach-imx/mm-imx5.c4
-rw-r--r--arch/arm/mach-imx/pm-imx5.c84
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);
142void imx6q_pm_set_ccm_base(void __iomem *base); 142void imx6q_pm_set_ccm_base(void __iomem *base);
143 143
144#ifdef CONFIG_PM 144#ifdef CONFIG_PM
145void imx5_pm_init(void); 145void imx51_pm_init(void);
146void imx53_pm_init(void);
146void imx5_pm_set_ccm_base(void __iomem *base); 147void imx5_pm_set_ccm_base(void __iomem *base);
147#else 148#else
148static inline void imx5_pm_init(void) {} 149static inline void imx51_pm_init(void) {}
150static inline void imx53_pm_init(void) {}
149static inline void imx5_pm_set_ccm_base(void __iomem *base) {} 151static 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)
96void __init imx51_init_late(void) 96void __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
102void __init imx53_init_late(void) 102void __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
52struct imx5_pm_data {
53 phys_addr_t cortex_addr;
54 phys_addr_t gpc_addr;
55};
56
57static const struct imx5_pm_data imx51_pm_data __initconst = {
58 .cortex_addr = 0x83fa0000,
59 .gpc_addr = 0x73fd8000,
60};
61
62static const struct imx5_pm_data imx53_pm_data __initconst = {
63 .cortex_addr = 0x63fa0000,
64 .gpc_addr = 0x53fd8000,
65};
66
59static void __iomem *ccm_base; 67static void __iomem *ccm_base;
68static void __iomem *cortex_base;
69static void __iomem *gpc_base;
60 70
61void __init imx5_pm_set_ccm_base(void __iomem *base) 71void __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
184static int __init imx5_pm_common_init(void) 197static 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
227void __init imx51_pm_init(void)
228{
229 imx5_pm_common_init(&imx51_pm_data);
204} 230}
205 231
206void __init imx5_pm_init(void) 232void __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}