[lantiq]
[openwrt.git] / target / linux / lantiq / patches-3.0 / 0021-MIPS-lantiq-adds-cache-split.patch
1 From 0f85e79f6f01f50cb703866a555085a9c65bad2f Mon Sep 17 00:00:00 2001
2 From: John Crispin <blogic@openwrt.org>
3 Date: Thu, 29 Sep 2011 20:31:54 +0200
4 Subject: [PATCH 21/24] MIPS: lantiq: adds cache split
5
6 ---
7  arch/mips/Kconfig      |   22 ++++++
8  arch/mips/kernel/vpe.c |   66 ++++++++++++++++++
9  arch/mips/mm/c-r4k.c   |  172 ++++++++++++++++++++++++++++++++++++++++++++++++
10  3 files changed, 260 insertions(+), 0 deletions(-)
11
12 Index: linux-3.0.3/arch/mips/Kconfig
13 ===================================================================
14 --- linux-3.0.3.orig/arch/mips/Kconfig  2011-10-05 12:53:54.792898260 +0200
15 +++ linux-3.0.3/arch/mips/Kconfig       2011-10-05 12:53:54.852898263 +0200
16 @@ -1913,6 +1913,28 @@
17         help
18           IFX included extensions in APRP
19  
20 +config IFX_VPE_CACHE_SPLIT
21 +       bool "IFX Cache Split Ways"
22 +       depends on IFX_VPE_EXT
23 +       help
24 +         IFX extension for reserving (splitting) cache ways among VPEs. You must
25 +         give kernel command line arguments vpe_icache_shared=0 or
26 +         vpe_dcache_shared=0 to enable splitting of icache or dcache
27 +         respectively. Then you can specify which cache ways should be
28 +         assigned to which VPE. There are total 8 cache ways, 4 each
29 +         for dcache and icache: dcache_way0, dcache_way1,dcache_way2,
30 +         dcache_way3 and icache_way0,icache_way1, icache_way2,icache_way3.
31 +
32 +         For example, if you specify vpe_icache_shared=0 and icache_way2=1,
33 +         then the 3rd icache way will be assigned to VPE0 and denied in VPE1.
34 +
35 +         For icache, software is required to make at least one cache way available
36 +         for a VPE at all times i.e., one can't assign all the icache ways to one
37 +         VPE.
38 +
39 +         By default, vpe_dcache_shared and vpe_icache_shared are set to 1
40 +         (i.e., both icache and dcache are shared among VPEs)
41 +
42  config PERFCTRS
43         bool "34K Performance counters"
44         depends on MIPS_MT && PROC_FS
45 Index: linux-3.0.3/arch/mips/kernel/vpe.c
46 ===================================================================
47 --- linux-3.0.3.orig/arch/mips/kernel/vpe.c     2011-10-05 12:53:54.800898262 +0200
48 +++ linux-3.0.3/arch/mips/kernel/vpe.c  2011-10-05 12:53:54.852898263 +0200
49 @@ -128,6 +128,13 @@
50  EXPORT_SYMBOL(vpe1_wdog_timeout);
51  
52  #endif
53 +
54 +#ifdef CONFIG_IFX_VPE_CACHE_SPLIT /* Code for splitting the cache ways among VPEs. */
55 +extern int vpe_icache_shared,vpe_dcache_shared;
56 +extern int icache_way0,icache_way1,icache_way2,icache_way3;
57 +extern int dcache_way0,dcache_way1,dcache_way2,dcache_way3;
58 +#endif
59 +
60  /* grab the likely amount of memory we will need. */
61  #ifdef CONFIG_MIPS_VPE_LOADER_TOM
62  #define P_SIZE (2 * 1024 * 1024)
63 @@ -866,6 +873,65 @@
64         /* enable this VPE */
65         write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA);
66  
67 +#ifdef CONFIG_IFX_VPE_CACHE_SPLIT
68 +       if ( (!vpe_icache_shared) || (!vpe_dcache_shared) ) {
69 +
70 +               /* PCP bit must be 1 to split the cache */
71 +               if(read_c0_mvpconf0() & MVPCONF0_PCP) {
72 +
73 +                       if ( !vpe_icache_shared ){
74 +                               write_vpe_c0_vpeconf0((read_vpe_c0_vpeconf0()) & ~VPECONF0_ICS);
75 +
76 +                               /*
77 +                                * If any cache way is 1, then that way is denied
78 +                                * in VPE1. Otherwise assign that way to VPE1.
79 +                                */
80 +                               if (!icache_way0)
81 +                                       write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() | VPEOPT_IWX0 );
82 +                               else
83 +                                       write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() & ~VPEOPT_IWX0 );
84 +                               if (!icache_way1)
85 +                                       write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() | VPEOPT_IWX1 );
86 +                               else
87 +                                       write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() & ~VPEOPT_IWX1 );
88 +                               if (!icache_way2)
89 +                                       write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() | VPEOPT_IWX2 );
90 +                               else
91 +                                       write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() & ~VPEOPT_IWX2 );
92 +                               if (!icache_way3)
93 +                                       write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() | VPEOPT_IWX3 );
94 +                               else
95 +                                       write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() & ~VPEOPT_IWX3 );
96 +                       }
97 +
98 +                       if ( !vpe_dcache_shared ) {
99 +                               write_vpe_c0_vpeconf0((read_vpe_c0_vpeconf0()) & ~VPECONF0_DCS);
100 +
101 +                               /*
102 +                                * If any cache way is 1, then that way is denied
103 +                                * in VPE1. Otherwise assign that way to VPE1.
104 +                                */
105 +                               if (!dcache_way0)
106 +                                       write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() | VPEOPT_DWX0 );
107 +                               else
108 +                                       write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() & ~VPEOPT_DWX0 );
109 +                               if (!dcache_way1)
110 +                                       write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() | VPEOPT_DWX1 );
111 +                               else
112 +                                       write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() & ~VPEOPT_DWX1 );
113 +                               if (!dcache_way2)
114 +                                       write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() | VPEOPT_DWX2 );
115 +                               else
116 +                                       write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() & ~VPEOPT_DWX2 );
117 +                               if (!dcache_way3)
118 +                                       write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() | VPEOPT_DWX3 );
119 +                               else
120 +                                       write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() & ~VPEOPT_DWX3 );
121 +                       }
122 +               }
123 +       }
124 +#endif /* endif CONFIG_IFX_VPE_CACHE_SPLIT */
125 +
126         /* clear out any left overs from a previous program */
127         write_vpe_c0_status(0);
128         write_vpe_c0_cause(0);
129 Index: linux-3.0.3/arch/mips/mm/c-r4k.c
130 ===================================================================
131 --- linux-3.0.3.orig/arch/mips/mm/c-r4k.c       2011-08-17 19:57:16.000000000 +0200
132 +++ linux-3.0.3/arch/mips/mm/c-r4k.c    2011-10-05 12:53:54.852898263 +0200
133 @@ -1346,6 +1346,106 @@
134  __setup("coherentio", setcoherentio);
135  #endif
136  
137 +#ifdef CONFIG_IFX_VPE_CACHE_SPLIT /* Code for splitting the cache ways among VPEs. */
138 +
139 +#include <asm/mipsmtregs.h>
140 +
141 +/*
142 + * By default, vpe_icache_shared and vpe_dcache_shared
143 + * values are 1 i.e., both icache and dcache are shared
144 + * among the VPEs.
145 + */
146 +
147 +int vpe_icache_shared = 1;
148 +static int __init vpe_icache_shared_val(char *str)
149 +{
150 +       get_option(&str, &vpe_icache_shared);
151 +       return 1;
152 +}
153 +__setup("vpe_icache_shared=", vpe_icache_shared_val);
154 +EXPORT_SYMBOL(vpe_icache_shared);
155 +
156 +int vpe_dcache_shared = 1;
157 +static int __init vpe_dcache_shared_val(char *str)
158 +{
159 +       get_option(&str, &vpe_dcache_shared);
160 +       return 1;
161 +}
162 +__setup("vpe_dcache_shared=", vpe_dcache_shared_val);
163 +EXPORT_SYMBOL(vpe_dcache_shared);
164 +
165 +/*
166 + * Software is required to make atleast one icache
167 + * way available for a VPE at all times i.e., one
168 + * can't assign all the icache ways to one VPE.
169 + */
170 +
171 +int icache_way0 = 0;
172 +static int __init icache_way0_val(char *str)
173 +{
174 +       get_option(&str, &icache_way0);
175 +       return 1;
176 +}
177 +__setup("icache_way0=", icache_way0_val);
178 +
179 +int icache_way1 = 0;
180 +static int __init icache_way1_val(char *str)
181 +{
182 +       get_option(&str, &icache_way1);
183 +       return 1;
184 +}
185 +__setup("icache_way1=", icache_way1_val);
186 +
187 +int icache_way2 = 0;
188 +static int __init icache_way2_val(char *str)
189 +{
190 +       get_option(&str, &icache_way2);
191 +       return 1;
192 +}
193 +__setup("icache_way2=", icache_way2_val);
194 +
195 +int icache_way3 = 0;
196 +static int __init icache_way3_val(char *str)
197 +{
198 +       get_option(&str, &icache_way3);
199 +       return 1;
200 +}
201 +__setup("icache_way3=", icache_way3_val);
202 +
203 +int dcache_way0 = 0;
204 +static int __init dcache_way0_val(char *str)
205 +{
206 +       get_option(&str, &dcache_way0);
207 +       return 1;
208 +}
209 +__setup("dcache_way0=", dcache_way0_val);
210 +
211 +int dcache_way1 = 0;
212 +static int __init dcache_way1_val(char *str)
213 +{
214 +       get_option(&str, &dcache_way1);
215 +       return 1;
216 +}
217 +__setup("dcache_way1=", dcache_way1_val);
218 +
219 +int dcache_way2 = 0;
220 +static int __init dcache_way2_val(char *str)
221 +{
222 +       get_option(&str, &dcache_way2);
223 +       return 1;
224 +}
225 +__setup("dcache_way2=", dcache_way2_val);
226 +
227 +int dcache_way3 = 0;
228 +static int __init dcache_way3_val(char *str)
229 +{
230 +       get_option(&str, &dcache_way3);
231 +       return 1;
232 +}
233 +__setup("dcache_way3=", dcache_way3_val);
234 +
235 +#endif /* endif CONFIG_IFX_VPE_CACHE_SPLIT */
236 +
237  void __cpuinit r4k_cache_init(void)
238  {
239         extern void build_clear_page(void);
240 @@ -1365,6 +1465,78 @@
241                 break;
242         }
243  
244 +#ifdef CONFIG_IFX_VPE_CACHE_SPLIT
245 +       /*
246 +        * We split the cache ways appropriately among the VPEs
247 +        * based on cache ways values we received as command line
248 +        * arguments
249 +        */
250 +       if ( (!vpe_icache_shared) || (!vpe_dcache_shared) ){
251 +
252 +               /* PCP bit must be 1 to split the cache */
253 +               if(read_c0_mvpconf0() & MVPCONF0_PCP) {
254 +
255 +                       /* Set CPA bit which enables us to modify VPEOpt register */
256 +                       write_c0_mvpcontrol((read_c0_mvpcontrol()) | MVPCONTROL_CPA);
257 +
258 +                       if ( !vpe_icache_shared ){
259 +                               write_c0_vpeconf0((read_c0_vpeconf0()) & ~VPECONF0_ICS);
260 +                               /*
261 +                                * If any cache way is 1, then that way is denied
262 +                                * in VPE0. Otherwise assign that way to VPE0.
263 +                                */
264 +                               printk(KERN_DEBUG "icache is split\n");
265 +                               printk(KERN_DEBUG "icache_way0=%d icache_way1=%d icache_way2=%d icache_way3=%d\n",
266 +                                       icache_way0, icache_way1,icache_way2, icache_way3);
267 +                               if (icache_way0)
268 +                                       write_c0_vpeopt(read_c0_vpeopt() | VPEOPT_IWX0 );
269 +                               else
270 +                                       write_c0_vpeopt(read_c0_vpeopt() & ~VPEOPT_IWX0 );
271 +                               if (icache_way1)
272 +                                       write_c0_vpeopt(read_c0_vpeopt() | VPEOPT_IWX1 );
273 +                               else
274 +                                       write_c0_vpeopt(read_c0_vpeopt() & ~VPEOPT_IWX1 );
275 +                               if (icache_way2)
276 +                                       write_c0_vpeopt(read_c0_vpeopt() | VPEOPT_IWX2 );
277 +                               else
278 +                                       write_c0_vpeopt(read_c0_vpeopt() & ~VPEOPT_IWX2 );
279 +                               if (icache_way3)
280 +                                       write_c0_vpeopt(read_c0_vpeopt() | VPEOPT_IWX3 );
281 +                               else
282 +                                       write_c0_vpeopt(read_c0_vpeopt() & ~VPEOPT_IWX3 );
283 +                       }
284 +
285 +                       if ( !vpe_dcache_shared ) {
286 +                               /*
287 +                                * If any cache way is 1, then that way is denied
288 +                                * in VPE0. Otherwise assign that way to VPE0.
289 +                                */
290 +                               printk(KERN_DEBUG "dcache is split\n");
291 +                               printk(KERN_DEBUG "dcache_way0=%d dcache_way1=%d dcache_way2=%d dcache_way3=%d\n",
292 +                                       dcache_way0, dcache_way1, dcache_way2, dcache_way3);
293 +                               write_c0_vpeconf0((read_c0_vpeconf0()) & ~VPECONF0_DCS);
294 +                               if (dcache_way0)
295 +                                       write_c0_vpeopt(read_c0_vpeopt() | VPEOPT_DWX0 );
296 +                               else
297 +                                       write_c0_vpeopt(read_c0_vpeopt() & ~VPEOPT_DWX0 );
298 +                               if (dcache_way1)
299 +                                       write_c0_vpeopt(read_c0_vpeopt() | VPEOPT_DWX1 );
300 +                               else
301 +                                       write_c0_vpeopt(read_c0_vpeopt() & ~VPEOPT_DWX1 );
302 +                               if (dcache_way2)
303 +                                       write_c0_vpeopt(read_c0_vpeopt() | VPEOPT_DWX2 );
304 +                               else
305 +                                       write_c0_vpeopt(read_c0_vpeopt() & ~VPEOPT_DWX2 );
306 +                               if (dcache_way3)
307 +                                       write_c0_vpeopt(read_c0_vpeopt() | VPEOPT_DWX3 );
308 +                               else
309 +                                       write_c0_vpeopt(read_c0_vpeopt() & ~VPEOPT_DWX3 );
310 +                       }
311 +               }
312 +       }
313 +
314 +#endif /* endif CONFIG_IFX_VPE_CACHE_SPLIT */
315 +
316         probe_pcache();
317         setup_scache();
318  
319 Index: linux-3.0.3/arch/mips/lantiq/setup.c
320 ===================================================================
321 --- linux-3.0.3.orig/arch/mips/lantiq/setup.c   2011-10-05 13:20:49.808967301 +0200
322 +++ linux-3.0.3/arch/mips/lantiq/setup.c        2011-10-05 13:23:27.796974054 +0200
323 @@ -18,10 +18,11 @@
324  #include "devices.h"
325  #include "prom.h"
326  
327 +/* assume 16M as default incase uboot fails to pass proper ramsize */
328 +unsigned long physical_memsize = 16L;
329 +
330  void __init plat_mem_setup(void)
331  {
332 -       /* assume 16M as default incase uboot fails to pass proper ramsize */
333 -       unsigned long memsize = 16;
334         char **envp = (char **) KSEG1ADDR(fw_arg2);
335  
336         ioport_resource.start = IOPORT_RESOURCE_START;
337 @@ -35,13 +36,13 @@
338                 char *e = (char *)KSEG1ADDR(*envp);
339                 if (!strncmp(e, "memsize=", 8)) {
340                         e += 8;
341 -                       if (strict_strtoul(e, 0, &memsize))
342 +                       if (strict_strtoul(e, 0, &physical_memsize))
343                                 pr_warn("bad memsize specified\n");
344                 }
345                 envp++;
346         }
347 -       memsize *= 1024 * 1024;
348 -       add_memory_region(0x00000000, memsize, BOOT_MEM_RAM);
349 +       physical_memsize *= 1024 * 1024;
350 +       add_memory_region(0x00000000, physical_memsize, BOOT_MEM_RAM);
351  }
352  
353  static int __init