0021-MIPS-lantiq-adds-cache-split.patch 11 KB

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