aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/mach-common
diff options
context:
space:
mode:
authorYi Li <yi.li@analog.com>2009-08-06 21:20:58 -0400
committerMike Frysinger <vapier@gentoo.org>2009-09-16 22:10:19 -0400
commiteb7bd9c461bbfbb195cb1e1346453222a4352df4 (patch)
tree9c92f6ce5160b655213bbcff8175878771594121 /arch/blackfin/mach-common
parent8312440e05ea74feabc648ad8f36c823af4ddd8e (diff)
Blackfin: cleanup sync handling when enabling/disabling cplbs
The handling of updating the [DI]MEM_CONTROL MMRs does not follow proper sync procedures as laid out in the Blackfin programming manual. So rather than audit/fix every call location, create helper functions that do the right things in order to safely update these MMRs. Then convert all call sites to use these new helper functions. While we're fixing the code, drop the workaround for anomaly 05000125 as that anomaly applies to old versions of silicon that we do not support. Signed-off-by: Yi Li <yi.li@analog.com> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'arch/blackfin/mach-common')
-rw-r--r--arch/blackfin/mach-common/entry.S14
-rw-r--r--arch/blackfin/mach-common/pm.c64
2 files changed, 12 insertions, 66 deletions
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
index 4e8e3fe0ba1c..e7eb16355f74 100644
--- a/arch/blackfin/mach-common/entry.S
+++ b/arch/blackfin/mach-common/entry.S
@@ -397,8 +397,7 @@ ENTRY(_double_fault)
397 397
398 R5 = [P4]; /* Control Register*/ 398 R5 = [P4]; /* Control Register*/
399 BITCLR(R5,ENICPLB_P); 399 BITCLR(R5,ENICPLB_P);
400 SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */ 400 CSYNC; /* Disabling of CPLBs should be proceeded by a CSYNC */
401 .align 8;
402 [P4] = R5; 401 [P4] = R5;
403 SSYNC; 402 SSYNC;
404 403
@@ -406,8 +405,7 @@ ENTRY(_double_fault)
406 P4.H = HI(DMEM_CONTROL); 405 P4.H = HI(DMEM_CONTROL);
407 R5 = [P4]; 406 R5 = [P4];
408 BITCLR(R5,ENDCPLB_P); 407 BITCLR(R5,ENDCPLB_P);
409 SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */ 408 CSYNC; /* Disabling of CPLBs should be proceeded by a CSYNC */
410 .align 8;
411 [P4] = R5; 409 [P4] = R5;
412 SSYNC; 410 SSYNC;
413 411
@@ -1146,9 +1144,7 @@ ENTRY(_early_trap)
1146 1144
1147 R5 = [P4]; /* Control Register*/ 1145 R5 = [P4]; /* Control Register*/
1148 BITCLR(R5,ENICPLB_P); 1146 BITCLR(R5,ENICPLB_P);
1149 CLI R1; 1147 CSYNC; /* Disabling of CPLBs should be proceeded by a CSYNC */
1150 SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */
1151 .align 8;
1152 [P4] = R5; 1148 [P4] = R5;
1153 SSYNC; 1149 SSYNC;
1154 1150
@@ -1156,11 +1152,9 @@ ENTRY(_early_trap)
1156 P4.H = HI(DMEM_CONTROL); 1152 P4.H = HI(DMEM_CONTROL);
1157 R5 = [P4]; 1153 R5 = [P4];
1158 BITCLR(R5,ENDCPLB_P); 1154 BITCLR(R5,ENDCPLB_P);
1159 SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */ 1155 CSYNC; /* Disabling of CPLBs should be proceeded by a CSYNC */
1160 .align 8;
1161 [P4] = R5; 1156 [P4] = R5;
1162 SSYNC; 1157 SSYNC;
1163 STI R1;
1164 1158
1165 r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */ 1159 r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */
1166 r1 = RETX; 1160 r1 = RETX;
diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c
index 9e7e27b7fc8d..0e3d4ff9d8b6 100644
--- a/arch/blackfin/mach-common/pm.c
+++ b/arch/blackfin/mach-common/pm.c
@@ -38,6 +38,7 @@
38#include <linux/io.h> 38#include <linux/io.h>
39#include <linux/irq.h> 39#include <linux/irq.h>
40 40
41#include <asm/cplb.h>
41#include <asm/gpio.h> 42#include <asm/gpio.h>
42#include <asm/dma.h> 43#include <asm/dma.h>
43#include <asm/dpmc.h> 44#include <asm/dpmc.h>
@@ -170,58 +171,6 @@ static void flushinv_all_dcache(void)
170} 171}
171#endif 172#endif
172 173
173static inline void dcache_disable(void)
174{
175#ifdef CONFIG_BFIN_DCACHE
176 unsigned long ctrl;
177
178#if defined(CONFIG_BFIN_EXTMEM_WRITEBACK) || defined(CONFIG_BFIN_L2_WRITEBACK)
179 flushinv_all_dcache();
180#endif
181 SSYNC();
182 ctrl = bfin_read_DMEM_CONTROL();
183 ctrl &= ~ENDCPLB;
184 bfin_write_DMEM_CONTROL(ctrl);
185 SSYNC();
186#endif
187}
188
189static inline void dcache_enable(void)
190{
191#ifdef CONFIG_BFIN_DCACHE
192 unsigned long ctrl;
193 SSYNC();
194 ctrl = bfin_read_DMEM_CONTROL();
195 ctrl |= ENDCPLB;
196 bfin_write_DMEM_CONTROL(ctrl);
197 SSYNC();
198#endif
199}
200
201static inline void icache_disable(void)
202{
203#ifdef CONFIG_BFIN_ICACHE
204 unsigned long ctrl;
205 SSYNC();
206 ctrl = bfin_read_IMEM_CONTROL();
207 ctrl &= ~ENICPLB;
208 bfin_write_IMEM_CONTROL(ctrl);
209 SSYNC();
210#endif
211}
212
213static inline void icache_enable(void)
214{
215#ifdef CONFIG_BFIN_ICACHE
216 unsigned long ctrl;
217 SSYNC();
218 ctrl = bfin_read_IMEM_CONTROL();
219 ctrl |= ENICPLB;
220 bfin_write_IMEM_CONTROL(ctrl);
221 SSYNC();
222#endif
223}
224
225int bfin_pm_suspend_mem_enter(void) 174int bfin_pm_suspend_mem_enter(void)
226{ 175{
227 unsigned long flags; 176 unsigned long flags;
@@ -258,16 +207,19 @@ int bfin_pm_suspend_mem_enter(void)
258 207
259 bfin_gpio_pm_hibernate_suspend(); 208 bfin_gpio_pm_hibernate_suspend();
260 209
261 dcache_disable(); 210#if defined(CONFIG_BFIN_EXTMEM_WRITEBACK) || defined(CONFIG_BFIN_L2_WRITEBACK)
262 icache_disable(); 211 flushinv_all_dcache();
212#endif
213 _disable_dcplb();
214 _disable_icplb();
263 bf53x_suspend_l1_mem(memptr); 215 bf53x_suspend_l1_mem(memptr);
264 216
265 do_hibernate(wakeup | vr_wakeup); /* Goodbye */ 217 do_hibernate(wakeup | vr_wakeup); /* Goodbye */
266 218
267 bf53x_resume_l1_mem(memptr); 219 bf53x_resume_l1_mem(memptr);
268 220
269 icache_enable(); 221 _enable_icplb();
270 dcache_enable(); 222 _enable_dcplb();
271 223
272 bfin_gpio_pm_hibernate_restore(); 224 bfin_gpio_pm_hibernate_restore();
273 blackfin_dma_resume(); 225 blackfin_dma_resume();