probe.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * arch/sh/kernel/cpu/sh4/probe.c
  4. *
  5. * CPU Subtype Probing for SH-4.
  6. *
  7. * Copyright (C) 2001 - 2007 Paul Mundt
  8. * Copyright (C) 2003 Richard Curnow
  9. */
  10. #include <linux/init.h>
  11. #include <linux/io.h>
  12. #include <asm/processor.h>
  13. #include <asm/cache.h>
  14. void cpu_probe(void)
  15. {
  16. unsigned long pvr, prr, cvr;
  17. unsigned long size;
  18. static unsigned long sizes[16] = {
  19. [1] = (1 << 12),
  20. [2] = (1 << 13),
  21. [4] = (1 << 14),
  22. [8] = (1 << 15),
  23. [9] = (1 << 16)
  24. };
  25. pvr = (__raw_readl(CCN_PVR) >> 8) & 0xffffff;
  26. prr = (__raw_readl(CCN_PRR) >> 4) & 0xff;
  27. cvr = (__raw_readl(CCN_CVR));
  28. /*
  29. * Setup some sane SH-4 defaults for the icache
  30. */
  31. boot_cpu_data.icache.way_incr = (1 << 13);
  32. boot_cpu_data.icache.entry_shift = 5;
  33. boot_cpu_data.icache.sets = 256;
  34. boot_cpu_data.icache.ways = 1;
  35. boot_cpu_data.icache.linesz = L1_CACHE_BYTES;
  36. /*
  37. * And again for the dcache ..
  38. */
  39. boot_cpu_data.dcache.way_incr = (1 << 14);
  40. boot_cpu_data.dcache.entry_shift = 5;
  41. boot_cpu_data.dcache.sets = 512;
  42. boot_cpu_data.dcache.ways = 1;
  43. boot_cpu_data.dcache.linesz = L1_CACHE_BYTES;
  44. /* We don't know the chip cut */
  45. boot_cpu_data.cut_major = boot_cpu_data.cut_minor = -1;
  46. /*
  47. * Setup some generic flags we can probe on SH-4A parts
  48. */
  49. if (((pvr >> 16) & 0xff) == 0x10) {
  50. boot_cpu_data.family = CPU_FAMILY_SH4A;
  51. if ((cvr & 0x10000000) == 0) {
  52. boot_cpu_data.flags |= CPU_HAS_DSP;
  53. boot_cpu_data.family = CPU_FAMILY_SH4AL_DSP;
  54. }
  55. boot_cpu_data.flags |= CPU_HAS_LLSC | CPU_HAS_PERF_COUNTER;
  56. boot_cpu_data.cut_major = pvr & 0x7f;
  57. boot_cpu_data.icache.ways = 4;
  58. boot_cpu_data.dcache.ways = 4;
  59. } else {
  60. /* And some SH-4 defaults.. */
  61. boot_cpu_data.flags |= CPU_HAS_PTEA | CPU_HAS_FPU;
  62. boot_cpu_data.family = CPU_FAMILY_SH4;
  63. }
  64. /* FPU detection works for almost everyone */
  65. if ((cvr & 0x20000000))
  66. boot_cpu_data.flags |= CPU_HAS_FPU;
  67. /* Mask off the upper chip ID */
  68. pvr &= 0xffff;
  69. /*
  70. * Probe the underlying processor version/revision and
  71. * adjust cpu_data setup accordingly.
  72. */
  73. switch (pvr) {
  74. case 0x205:
  75. boot_cpu_data.type = CPU_SH7750;
  76. boot_cpu_data.flags |= CPU_HAS_P2_FLUSH_BUG |
  77. CPU_HAS_PERF_COUNTER;
  78. break;
  79. case 0x206:
  80. boot_cpu_data.type = CPU_SH7750S;
  81. boot_cpu_data.flags |= CPU_HAS_P2_FLUSH_BUG |
  82. CPU_HAS_PERF_COUNTER;
  83. break;
  84. case 0x1100:
  85. boot_cpu_data.type = CPU_SH7751;
  86. break;
  87. case 0x2001:
  88. case 0x2004:
  89. boot_cpu_data.type = CPU_SH7770;
  90. break;
  91. case 0x2006:
  92. case 0x200A:
  93. if (prr == 0x61)
  94. boot_cpu_data.type = CPU_SH7781;
  95. else if (prr == 0xa1)
  96. boot_cpu_data.type = CPU_SH7763;
  97. else
  98. boot_cpu_data.type = CPU_SH7780;
  99. break;
  100. case 0x3000:
  101. case 0x3003:
  102. case 0x3009:
  103. boot_cpu_data.type = CPU_SH7343;
  104. break;
  105. case 0x3004:
  106. case 0x3007:
  107. boot_cpu_data.type = CPU_SH7785;
  108. break;
  109. case 0x4004:
  110. case 0x4005:
  111. boot_cpu_data.type = CPU_SH7786;
  112. boot_cpu_data.flags |= CPU_HAS_PTEAEX | CPU_HAS_L2_CACHE;
  113. break;
  114. case 0x3008:
  115. switch (prr) {
  116. case 0x50:
  117. case 0x51:
  118. boot_cpu_data.type = CPU_SH7723;
  119. boot_cpu_data.flags |= CPU_HAS_L2_CACHE;
  120. break;
  121. case 0x70:
  122. boot_cpu_data.type = CPU_SH7366;
  123. break;
  124. case 0xa0:
  125. case 0xa1:
  126. boot_cpu_data.type = CPU_SH7722;
  127. break;
  128. }
  129. break;
  130. case 0x300b:
  131. switch (prr) {
  132. case 0x20:
  133. boot_cpu_data.type = CPU_SH7724;
  134. boot_cpu_data.flags |= CPU_HAS_L2_CACHE;
  135. break;
  136. case 0x10:
  137. case 0x11:
  138. boot_cpu_data.type = CPU_SH7757;
  139. break;
  140. case 0xd0:
  141. case 0x40: /* yon-ten-go */
  142. boot_cpu_data.type = CPU_SH7372;
  143. break;
  144. case 0xE0: /* 0x4E0 */
  145. boot_cpu_data.type = CPU_SH7734; /* SH7733/SH7734 */
  146. break;
  147. }
  148. break;
  149. case 0x4000: /* 1st cut */
  150. case 0x4001: /* 2nd cut */
  151. boot_cpu_data.type = CPU_SHX3;
  152. break;
  153. case 0x700:
  154. boot_cpu_data.type = CPU_SH4_501;
  155. boot_cpu_data.flags &= ~CPU_HAS_FPU;
  156. boot_cpu_data.icache.ways = 2;
  157. boot_cpu_data.dcache.ways = 2;
  158. break;
  159. case 0x600:
  160. boot_cpu_data.type = CPU_SH4_202;
  161. boot_cpu_data.icache.ways = 2;
  162. boot_cpu_data.dcache.ways = 2;
  163. break;
  164. case 0x500 ... 0x501:
  165. switch (prr) {
  166. case 0x10:
  167. boot_cpu_data.type = CPU_SH7750R;
  168. break;
  169. case 0x11:
  170. boot_cpu_data.type = CPU_SH7751R;
  171. break;
  172. case 0x50 ... 0x5f:
  173. boot_cpu_data.type = CPU_SH7760;
  174. break;
  175. }
  176. boot_cpu_data.icache.ways = 2;
  177. boot_cpu_data.dcache.ways = 2;
  178. break;
  179. }
  180. /*
  181. * On anything that's not a direct-mapped cache, look to the CVR
  182. * for I/D-cache specifics.
  183. */
  184. if (boot_cpu_data.icache.ways > 1) {
  185. size = sizes[(cvr >> 20) & 0xf];
  186. boot_cpu_data.icache.way_incr = (size >> 1);
  187. boot_cpu_data.icache.sets = (size >> 6);
  188. }
  189. /* And the rest of the D-cache */
  190. if (boot_cpu_data.dcache.ways > 1) {
  191. size = sizes[(cvr >> 16) & 0xf];
  192. boot_cpu_data.dcache.way_incr = (size >> 1);
  193. boot_cpu_data.dcache.sets = (size >> 6);
  194. }
  195. /*
  196. * SH-4A's have an optional PIPT L2.
  197. */
  198. if (boot_cpu_data.flags & CPU_HAS_L2_CACHE) {
  199. /*
  200. * Verify that it really has something hooked up, this
  201. * is the safety net for CPUs that have optional L2
  202. * support yet do not implement it.
  203. */
  204. if ((cvr & 0xf) == 0)
  205. boot_cpu_data.flags &= ~CPU_HAS_L2_CACHE;
  206. else {
  207. /*
  208. * Silicon and specifications have clearly never
  209. * met..
  210. */
  211. cvr ^= 0xf;
  212. /*
  213. * Size calculation is much more sensible
  214. * than it is for the L1.
  215. *
  216. * Sizes are 128KB, 256KB, 512KB, and 1MB.
  217. */
  218. size = (cvr & 0xf) << 17;
  219. boot_cpu_data.scache.way_incr = (1 << 16);
  220. boot_cpu_data.scache.entry_shift = 5;
  221. boot_cpu_data.scache.ways = 4;
  222. boot_cpu_data.scache.linesz = L1_CACHE_BYTES;
  223. boot_cpu_data.scache.entry_mask =
  224. (boot_cpu_data.scache.way_incr -
  225. boot_cpu_data.scache.linesz);
  226. boot_cpu_data.scache.sets = size /
  227. (boot_cpu_data.scache.linesz *
  228. boot_cpu_data.scache.ways);
  229. boot_cpu_data.scache.way_size =
  230. (boot_cpu_data.scache.sets *
  231. boot_cpu_data.scache.linesz);
  232. }
  233. }
  234. }