l2cache.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. #include <linux/init.h>
  2. #include <linux/kernel.h>
  3. #include <linux/delay.h>
  4. #include <asm/l2cache.h>
  5. #include <asm/metag_isa.h>
  6. /* If non-0, then initialise the L2 cache */
  7. static int l2cache_init = 1;
  8. /* If non-0, then initialise the L2 cache prefetch */
  9. static int l2cache_init_pf = 1;
  10. int l2c_pfenable;
  11. static volatile u32 l2c_testdata[16] __initdata __aligned(64);
  12. static int __init parse_l2cache(char *p)
  13. {
  14. char *cp = p;
  15. if (get_option(&cp, &l2cache_init) != 1) {
  16. pr_err("Bad l2cache parameter (%s)\n", p);
  17. return 1;
  18. }
  19. return 0;
  20. }
  21. early_param("l2cache", parse_l2cache);
  22. static int __init parse_l2cache_pf(char *p)
  23. {
  24. char *cp = p;
  25. if (get_option(&cp, &l2cache_init_pf) != 1) {
  26. pr_err("Bad l2cache_pf parameter (%s)\n", p);
  27. return 1;
  28. }
  29. return 0;
  30. }
  31. early_param("l2cache_pf", parse_l2cache_pf);
  32. static int __init meta_l2c_setup(void)
  33. {
  34. /*
  35. * If the L2 cache isn't even present, don't do anything, but say so in
  36. * the log.
  37. */
  38. if (!meta_l2c_is_present()) {
  39. pr_info("L2 Cache: Not present\n");
  40. return 0;
  41. }
  42. /*
  43. * Check whether the line size is recognised.
  44. */
  45. if (!meta_l2c_linesize()) {
  46. pr_warn_once("L2 Cache: unknown line size id (config=0x%08x)\n",
  47. meta_l2c_config());
  48. }
  49. /*
  50. * Initialise state.
  51. */
  52. l2c_pfenable = _meta_l2c_pf_is_enabled();
  53. /*
  54. * Enable the L2 cache and print to log whether it was already enabled
  55. * by the bootloader.
  56. */
  57. if (l2cache_init) {
  58. pr_info("L2 Cache: Enabling... ");
  59. if (meta_l2c_enable())
  60. pr_cont("already enabled\n");
  61. else
  62. pr_cont("done\n");
  63. } else {
  64. pr_info("L2 Cache: Not enabling\n");
  65. }
  66. /*
  67. * Enable L2 cache prefetch.
  68. */
  69. if (l2cache_init_pf) {
  70. pr_info("L2 Cache: Enabling prefetch... ");
  71. if (meta_l2c_pf_enable(1))
  72. pr_cont("already enabled\n");
  73. else
  74. pr_cont("done\n");
  75. } else {
  76. pr_info("L2 Cache: Not enabling prefetch\n");
  77. }
  78. return 0;
  79. }
  80. core_initcall(meta_l2c_setup);
  81. int meta_l2c_disable(void)
  82. {
  83. unsigned long flags;
  84. int en;
  85. if (!meta_l2c_is_present())
  86. return 1;
  87. /*
  88. * Prevent other threads writing during the writeback, otherwise the
  89. * writes will get "lost" when the L2 is disabled.
  90. */
  91. __global_lock2(flags);
  92. en = meta_l2c_is_enabled();
  93. if (likely(en)) {
  94. _meta_l2c_pf_enable(0);
  95. wr_fence();
  96. _meta_l2c_purge();
  97. _meta_l2c_enable(0);
  98. }
  99. __global_unlock2(flags);
  100. return !en;
  101. }
  102. int meta_l2c_enable(void)
  103. {
  104. unsigned long flags;
  105. int en;
  106. if (!meta_l2c_is_present())
  107. return 0;
  108. /*
  109. * Init (clearing the L2) can happen while the L2 is disabled, so other
  110. * threads are safe to continue executing, however we must not init the
  111. * cache if it's already enabled (dirty lines would be discarded), so
  112. * this operation should still be atomic with other threads.
  113. */
  114. __global_lock1(flags);
  115. en = meta_l2c_is_enabled();
  116. if (likely(!en)) {
  117. _meta_l2c_init();
  118. _meta_l2c_enable(1);
  119. _meta_l2c_pf_enable(l2c_pfenable);
  120. }
  121. __global_unlock1(flags);
  122. return en;
  123. }
  124. int meta_l2c_pf_enable(int pfenable)
  125. {
  126. unsigned long flags;
  127. int en = l2c_pfenable;
  128. if (!meta_l2c_is_present())
  129. return 0;
  130. /*
  131. * We read modify write the enable register, so this operation must be
  132. * atomic with other threads.
  133. */
  134. __global_lock1(flags);
  135. en = l2c_pfenable;
  136. l2c_pfenable = pfenable;
  137. if (meta_l2c_is_enabled())
  138. _meta_l2c_pf_enable(pfenable);
  139. __global_unlock1(flags);
  140. return en;
  141. }
  142. int meta_l2c_flush(void)
  143. {
  144. unsigned long flags;
  145. int en;
  146. /*
  147. * Prevent other threads writing during the writeback. This also
  148. * involves read modify writes.
  149. */
  150. __global_lock2(flags);
  151. en = meta_l2c_is_enabled();
  152. if (likely(en)) {
  153. _meta_l2c_pf_enable(0);
  154. wr_fence();
  155. _meta_l2c_purge();
  156. _meta_l2c_enable(0);
  157. _meta_l2c_init();
  158. _meta_l2c_enable(1);
  159. _meta_l2c_pf_enable(l2c_pfenable);
  160. }
  161. __global_unlock2(flags);
  162. return !en;
  163. }