aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/kernel/cplb-nompu
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/kernel/cplb-nompu
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/kernel/cplb-nompu')
-rw-r--r--arch/blackfin/kernel/cplb-nompu/cacheinit.c6
-rw-r--r--arch/blackfin/kernel/cplb-nompu/cplbmgr.c33
2 files changed, 8 insertions, 31 deletions
diff --git a/arch/blackfin/kernel/cplb-nompu/cacheinit.c b/arch/blackfin/kernel/cplb-nompu/cacheinit.c
index d5a86c3017f7..a082681faa8e 100644
--- a/arch/blackfin/kernel/cplb-nompu/cacheinit.c
+++ b/arch/blackfin/kernel/cplb-nompu/cacheinit.c
@@ -30,13 +30,14 @@ void __cpuinit bfin_icache_init(struct cplb_entry *icplb_tbl)
30 unsigned long ctrl; 30 unsigned long ctrl;
31 int i; 31 int i;
32 32
33 SSYNC();
34 for (i = 0; i < MAX_CPLBS; i++) { 33 for (i = 0; i < MAX_CPLBS; i++) {
35 bfin_write32(ICPLB_ADDR0 + i * 4, icplb_tbl[i].addr); 34 bfin_write32(ICPLB_ADDR0 + i * 4, icplb_tbl[i].addr);
36 bfin_write32(ICPLB_DATA0 + i * 4, icplb_tbl[i].data); 35 bfin_write32(ICPLB_DATA0 + i * 4, icplb_tbl[i].data);
37 } 36 }
38 ctrl = bfin_read_IMEM_CONTROL(); 37 ctrl = bfin_read_IMEM_CONTROL();
39 ctrl |= IMC | ENICPLB; 38 ctrl |= IMC | ENICPLB;
39 /* CSYNC to ensure load store ordering */
40 CSYNC();
40 bfin_write_IMEM_CONTROL(ctrl); 41 bfin_write_IMEM_CONTROL(ctrl);
41 SSYNC(); 42 SSYNC();
42} 43}
@@ -48,7 +49,6 @@ void __cpuinit bfin_dcache_init(struct cplb_entry *dcplb_tbl)
48 unsigned long ctrl; 49 unsigned long ctrl;
49 int i; 50 int i;
50 51
51 SSYNC();
52 for (i = 0; i < MAX_CPLBS; i++) { 52 for (i = 0; i < MAX_CPLBS; i++) {
53 bfin_write32(DCPLB_ADDR0 + i * 4, dcplb_tbl[i].addr); 53 bfin_write32(DCPLB_ADDR0 + i * 4, dcplb_tbl[i].addr);
54 bfin_write32(DCPLB_DATA0 + i * 4, dcplb_tbl[i].data); 54 bfin_write32(DCPLB_DATA0 + i * 4, dcplb_tbl[i].data);
@@ -63,6 +63,8 @@ void __cpuinit bfin_dcache_init(struct cplb_entry *dcplb_tbl)
63 * to port B 63 * to port B
64 */ 64 */
65 ctrl |= DMEM_CNTR | PORT_PREF0 | (ANOMALY_05000287 ? PORT_PREF1 : 0); 65 ctrl |= DMEM_CNTR | PORT_PREF0 | (ANOMALY_05000287 ? PORT_PREF1 : 0);
66 /* CSYNC to ensure load store ordering */
67 CSYNC();
66 bfin_write_DMEM_CONTROL(ctrl); 68 bfin_write_DMEM_CONTROL(ctrl);
67 SSYNC(); 69 SSYNC();
68} 70}
diff --git a/arch/blackfin/kernel/cplb-nompu/cplbmgr.c b/arch/blackfin/kernel/cplb-nompu/cplbmgr.c
index 12b030842fdb..aabbb42c42c4 100644
--- a/arch/blackfin/kernel/cplb-nompu/cplbmgr.c
+++ b/arch/blackfin/kernel/cplb-nompu/cplbmgr.c
@@ -48,36 +48,13 @@ int nr_cplb_flush[NR_CPUS], nr_dcplb_prot[NR_CPUS];
48#define MGR_ATTR 48#define MGR_ATTR
49#endif 49#endif
50 50
51/*
52 * We're in an exception handler. The normal cli nop nop workaround
53 * isn't going to do very much, as the only thing that can interrupt
54 * us is an NMI, and the cli isn't going to stop that.
55 */
56#define NOWA_SSYNC __asm__ __volatile__ ("ssync;")
57
58/* Anomaly handlers provide SSYNCs, so avoid extra if anomaly is present */
59#if ANOMALY_05000125
60
61#define bfin_write_DMEM_CONTROL_SSYNC(v) bfin_write_DMEM_CONTROL(v)
62#define bfin_write_IMEM_CONTROL_SSYNC(v) bfin_write_IMEM_CONTROL(v)
63
64#else
65
66#define bfin_write_DMEM_CONTROL_SSYNC(v) \
67 do { NOWA_SSYNC; bfin_write_DMEM_CONTROL(v); NOWA_SSYNC; } while (0)
68#define bfin_write_IMEM_CONTROL_SSYNC(v) \
69 do { NOWA_SSYNC; bfin_write_IMEM_CONTROL(v); NOWA_SSYNC; } while (0)
70
71#endif
72
73static inline void write_dcplb_data(int cpu, int idx, unsigned long data, 51static inline void write_dcplb_data(int cpu, int idx, unsigned long data,
74 unsigned long addr) 52 unsigned long addr)
75{ 53{
76 unsigned long ctrl = bfin_read_DMEM_CONTROL(); 54 _disable_dcplb();
77 bfin_write_DMEM_CONTROL_SSYNC(ctrl & ~ENDCPLB);
78 bfin_write32(DCPLB_DATA0 + idx * 4, data); 55 bfin_write32(DCPLB_DATA0 + idx * 4, data);
79 bfin_write32(DCPLB_ADDR0 + idx * 4, addr); 56 bfin_write32(DCPLB_ADDR0 + idx * 4, addr);
80 bfin_write_DMEM_CONTROL_SSYNC(ctrl); 57 _enable_dcplb();
81 58
82#ifdef CONFIG_CPLB_INFO 59#ifdef CONFIG_CPLB_INFO
83 dcplb_tbl[cpu][idx].addr = addr; 60 dcplb_tbl[cpu][idx].addr = addr;
@@ -88,12 +65,10 @@ static inline void write_dcplb_data(int cpu, int idx, unsigned long data,
88static inline void write_icplb_data(int cpu, int idx, unsigned long data, 65static inline void write_icplb_data(int cpu, int idx, unsigned long data,
89 unsigned long addr) 66 unsigned long addr)
90{ 67{
91 unsigned long ctrl = bfin_read_IMEM_CONTROL(); 68 _disable_icplb();
92
93 bfin_write_IMEM_CONTROL_SSYNC(ctrl & ~ENICPLB);
94 bfin_write32(ICPLB_DATA0 + idx * 4, data); 69 bfin_write32(ICPLB_DATA0 + idx * 4, data);
95 bfin_write32(ICPLB_ADDR0 + idx * 4, addr); 70 bfin_write32(ICPLB_ADDR0 + idx * 4, addr);
96 bfin_write_IMEM_CONTROL_SSYNC(ctrl); 71 _enable_icplb();
97 72
98#ifdef CONFIG_CPLB_INFO 73#ifdef CONFIG_CPLB_INFO
99 icplb_tbl[cpu][idx].addr = addr; 74 icplb_tbl[cpu][idx].addr = addr;