add even more workarounds for bcm4710, remove -fno-delayed-branch from kernel cflags...
[openwrt.git] / openwrt / target / linux / linux-2.4 / patches / brcm / 004-bcm94710_mmu.patch
1 diff -urN linux.old/arch/mips/mm/c-r4k.c linux.dev/arch/mips/mm/c-r4k.c
2 --- linux.old/arch/mips/mm/c-r4k.c      2005-06-01 18:42:44.000000000 +0200
3 +++ linux.dev/arch/mips/mm/c-r4k.c      2005-06-01 18:49:07.000000000 +0200
4 @@ -14,6 +14,12 @@
5  #include <linux/mm.h>
6  #include <linux/bitops.h>
7  
8 +#ifdef CONFIG_BCM4710
9 +#include "../bcm947xx/include/typedefs.h"
10 +#include "../bcm947xx/include/sbconfig.h"
11 +#include <asm/paccess.h>
12 +#endif
13 +
14  #include <asm/bcache.h>
15  #include <asm/bootinfo.h>
16  #include <asm/cacheops.h>
17 @@ -390,6 +396,11 @@
18                         addr = start & ~(dc_lsize - 1);
19                         aend = (end - 1) & ~(dc_lsize - 1);
20  
21 +#ifdef CONFIG_BCM4710
22 +                       BCM4710_FILL_TLB(addr);
23 +                       BCM4710_FILL_TLB(aend);
24 +#endif
25 +
26                         while (1) {
27                                 /* Hit_Writeback_Inv_D */
28                                 protected_writeback_dcache_line(addr);
29 @@ -405,6 +416,10 @@
30         else {
31                 addr = start & ~(ic_lsize - 1);
32                 aend = (end - 1) & ~(ic_lsize - 1);
33 +#ifdef CONFIG_BCM4710
34 +               BCM4710_FILL_TLB(addr);
35 +               BCM4710_FILL_TLB(aend);
36 +#endif
37                 while (1) {
38                         /* Hit_Invalidate_I */
39                         protected_flush_icache_line(addr);
40 @@ -487,6 +502,10 @@
41  
42                 a = addr & ~(sc_lsize - 1);
43                 end = (addr + size - 1) & ~(sc_lsize - 1);
44 +#ifdef CONFIG_BCM4710
45 +               BCM4710_FILL_TLB(a);
46 +               BCM4710_FILL_TLB(end);
47 +#endif
48                 while (1) {
49                         flush_scache_line(a);   /* Hit_Writeback_Inv_SD */
50                         if (a == end)
51 @@ -509,6 +528,10 @@
52                 R4600_HIT_CACHEOP_WAR_IMPL;
53                 a = addr & ~(dc_lsize - 1);
54                 end = (addr + size - 1) & ~(dc_lsize - 1);
55 +#ifdef CONFIG_BCM4710
56 +               BCM4710_FILL_TLB(a);
57 +               BCM4710_FILL_TLB(end);
58 +#endif
59                 while (1) {
60                         flush_dcache_line(a);   /* Hit_Writeback_Inv_D */
61                         if (a == end)
62 @@ -537,6 +560,10 @@
63  
64                 a = addr & ~(sc_lsize - 1);
65                 end = (addr + size - 1) & ~(sc_lsize - 1);
66 +#ifdef CONFIG_BCM4710
67 +               BCM4710_FILL_TLB(a);
68 +               BCM4710_FILL_TLB(end);
69 +#endif
70                 while (1) {
71                         flush_scache_line(a);   /* Hit_Writeback_Inv_SD */
72                         if (a == end)
73 @@ -576,6 +603,10 @@
74         unsigned long ic_lsize = current_cpu_data.icache.linesz;
75         unsigned long dc_lsize = current_cpu_data.dcache.linesz;
76  
77 +#ifdef CONFIG_BCM4710
78 +       BCM4710_PROTECTED_FILL_TLB(addr);
79 +       BCM4710_PROTECTED_FILL_TLB(addr + 4);
80 +#endif
81         R4600_HIT_CACHEOP_WAR_IMPL;
82         protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
83         protected_flush_icache_line(addr & ~(ic_lsize - 1));
84 diff -urN linux.old/include/asm-mips/r4kcache.h linux.dev/include/asm-mips/r4kcache.h
85 --- linux.old/include/asm-mips/r4kcache.h       2005-06-01 18:42:43.000000000 +0200
86 +++ linux.dev/include/asm-mips/r4kcache.h       2005-06-01 19:07:11.000000000 +0200
87 @@ -15,6 +15,25 @@
88  #include <asm/asm.h>
89  #include <asm/cacheops.h>
90  
91 +#ifdef CONFIG_BCM4710
92 +#define BCM4710_DUMMY_RREG() (((sbconfig_t *)(KSEG1ADDR(SB_ENUM_BASE + SBCONFIGOFF)))->sbimstate)
93 +
94 +#define BCM4710_FILL_TLB(addr) (*(volatile unsigned long *)(addr))
95 +#define BCM4710_PROTECTED_FILL_TLB(addr) ({ unsigned long x; get_dbe(x, (volatile unsigned long *)(addr)); })
96 +
97 +#define cache_op(op,addr)                                              \
98 +       BCM4710_DUMMY_RREG();                                           \
99 +       __asm__ __volatile__(                                           \
100 +       "       .set    noreorder                               \n"     \
101 +       "       .set    mips3\n\t                               \n"     \
102 +       "       cache   %0, %1                                  \n"     \
103 +       "       .set    mips0                                   \n"     \
104 +       "       .set    reorder"                                        \
105 +       :                                                               \
106 +       : "i" (op), "m" (*(unsigned char *)(addr)))
107 +
108 +#else
109 +
110  #define cache_op(op,addr)                                              \
111         __asm__ __volatile__(                                           \
112         "       .set    noreorder                               \n"     \
113 @@ -24,6 +43,8 @@
114         "       .set    reorder"                                        \
115         :                                                               \
116         : "i" (op), "m" (*(unsigned char *)(addr)))
117 +#endif
118 +
119  
120  static inline void flush_icache_line_indexed(unsigned long addr)
121  {
122 @@ -32,6 +53,9 @@
123  
124  static inline void flush_dcache_line_indexed(unsigned long addr)
125  {
126 +#ifdef CONFIG_BCM4710  
127 +       BCM4710_DUMMY_RREG();
128 +#endif
129         cache_op(Index_Writeback_Inv_D, addr);
130  }
131  
132 @@ -47,6 +71,10 @@
133  
134  static inline void flush_dcache_line(unsigned long addr)
135  {
136 +
137 +#ifdef CONFIG_BCM4710  
138 +       BCM4710_DUMMY_RREG();
139 +#endif
140         cache_op(Hit_Writeback_Inv_D, addr);
141  }
142  
143 @@ -91,6 +119,9 @@
144   */
145  static inline void protected_writeback_dcache_line(unsigned long addr)
146  {
147 +#ifdef CONFIG_BCM4710  
148 +       BCM4710_DUMMY_RREG();
149 +#endif
150         __asm__ __volatile__(
151                 ".set noreorder\n\t"
152                 ".set mips3\n"
153 @@ -148,8 +179,12 @@
154         unsigned long ws, addr;
155  
156         for (ws = 0; ws < ws_end; ws += ws_inc) 
157 -               for (addr = start; addr < end; addr += 0x200)
158 +               for (addr = start; addr < end; addr += 0x200) {
159 +#ifdef CONFIG_BCM4710  
160 +                       BCM4710_DUMMY_RREG();
161 +#endif
162                         cache16_unroll32(addr|ws,Index_Writeback_Inv_D);
163 +               }
164  }
165  
166  static inline void blast_dcache16_page(unsigned long page)
167 @@ -158,6 +193,9 @@
168         unsigned long end = start + PAGE_SIZE;
169  
170         do {
171 +#ifdef CONFIG_BCM4710  
172 +               BCM4710_DUMMY_RREG();
173 +#endif
174                 cache16_unroll32(start,Hit_Writeback_Inv_D);
175                 start += 0x200;
176         } while (start < end);
177 @@ -173,8 +211,12 @@
178         unsigned long ws, addr;
179  
180         for (ws = 0; ws < ws_end; ws += ws_inc) 
181 -               for (addr = start; addr < end; addr += 0x200) 
182 +               for (addr = start; addr < end; addr += 0x200) {
183 +#ifdef CONFIG_BCM4710  
184 +                       BCM4710_DUMMY_RREG();
185 +#endif
186                         cache16_unroll32(addr|ws,Index_Writeback_Inv_D);
187 +               }
188  }
189  
190  static inline void blast_icache16(void)
191 @@ -196,7 +238,13 @@
192         unsigned long start = page;
193         unsigned long end = start + PAGE_SIZE;
194  
195 +#ifdef CONFIG_BCM4710  
196 +       BCM4710_FILL_TLB(start);
197 +#endif
198         do {
199 +#ifdef CONFIG_BCM4710  
200 +               BCM4710_DUMMY_RREG();
201 +#endif
202                 cache16_unroll32(start,Hit_Invalidate_I);
203                 start += 0x200;
204         } while (start < end);
205 @@ -291,8 +339,12 @@
206         unsigned long ws, addr;
207  
208         for (ws = 0; ws < ws_end; ws += ws_inc) 
209 -               for (addr = start; addr < end; addr += 0x400) 
210 +               for (addr = start; addr < end; addr += 0x400) {
211 +#ifdef CONFIG_BCM4710  
212 +                       BCM4710_DUMMY_RREG();
213 +#endif
214                         cache32_unroll32(addr|ws,Index_Writeback_Inv_D);
215 +               }
216  }
217  
218  static inline void blast_dcache32_page(unsigned long page)
219 @@ -300,7 +352,13 @@
220         unsigned long start = page;
221         unsigned long end = start + PAGE_SIZE;
222  
223 +#ifdef CONFIG_BCM4710  
224 +       __asm__ __volatile__("nop;nop;nop;nop");
225 +#endif
226         do {
227 +#ifdef CONFIG_BCM4710  
228 +               BCM4710_DUMMY_RREG();
229 +#endif
230                 cache32_unroll32(start,Hit_Writeback_Inv_D);
231                 start += 0x400;
232         } while (start < end);
233 @@ -339,6 +397,9 @@
234         unsigned long start = page;
235         unsigned long end = start + PAGE_SIZE;
236  
237 +#ifdef CONFIG_BCM4710  
238 +       BCM4710_FILL_TLB(start);
239 +#endif
240         do {
241                 cache32_unroll32(start,Hit_Invalidate_I);
242                 start += 0x400;