cpu.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2013-2014, 2018 Synopsys, Inc. All rights reserved.
  4. */
  5. #include <common.h>
  6. #include <init.h>
  7. #include <malloc.h>
  8. #include <vsprintf.h>
  9. #include <asm/arcregs.h>
  10. #include <asm/cache.h>
  11. #include <linux/bitops.h>
  12. DECLARE_GLOBAL_DATA_PTR;
  13. int arch_cpu_init(void)
  14. {
  15. timer_init();
  16. gd->cpu_clk = CONFIG_SYS_CLK_FREQ;
  17. gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
  18. cache_init();
  19. return 0;
  20. }
  21. /* This is a dummy function on arc */
  22. int dram_init(void)
  23. {
  24. return 0;
  25. }
  26. #ifdef CONFIG_DISPLAY_CPUINFO
  27. const char *arc_700_version(int arcver, char *name, int name_len)
  28. {
  29. const char *arc_ver;
  30. switch (arcver) {
  31. case 0x32:
  32. arc_ver = "v4.4-4.5";
  33. break;
  34. case 0x33:
  35. arc_ver = "v4.6-v4.9";
  36. break;
  37. case 0x34:
  38. arc_ver = "v4.10";
  39. break;
  40. case 0x35:
  41. arc_ver = "v4.11";
  42. break;
  43. default:
  44. arc_ver = "unknown version";
  45. }
  46. snprintf(name, name_len, "ARC 700 %s", arc_ver);
  47. return name;
  48. }
  49. struct em_template_t {
  50. const bool cache;
  51. const bool dsp;
  52. const bool xymem;
  53. const char name[8];
  54. };
  55. static const struct em_template_t em_versions[] = {
  56. {false, false, false, "EM4"},
  57. {true, false, false, "EM6"},
  58. {false, true, false, "EM5D"},
  59. {true, true, false, "EM7D"},
  60. {false, true, true, "EM9D"},
  61. {true, true, true, "EM11D"},
  62. };
  63. const char *arc_em_version(int arcver, char *name, int name_len)
  64. {
  65. const char *arc_name = "EM";
  66. const char *arc_ver;
  67. bool cache = ARC_FEATURE_EXISTS(ARC_BCR_IC_BUILD);
  68. bool dsp = ARC_FEATURE_EXISTS(ARC_AUX_DSP_BUILD);
  69. bool xymem = ARC_FEATURE_EXISTS(ARC_AUX_XY_BUILD);
  70. int i;
  71. for (i = 0; i < sizeof(em_versions) / sizeof(struct em_template_t); i++) {
  72. if (em_versions[i].cache == cache &&
  73. em_versions[i].dsp == dsp &&
  74. em_versions[i].xymem == xymem) {
  75. arc_name = em_versions[i].name;
  76. break;
  77. }
  78. }
  79. switch (arcver) {
  80. case 0x41:
  81. arc_ver = "v1.1a";
  82. break;
  83. case 0x42:
  84. arc_ver = "v3.0";
  85. break;
  86. case 0x43:
  87. arc_ver = "v4.0";
  88. break;
  89. case 0x44:
  90. arc_ver = "v5.0";
  91. break;
  92. default:
  93. arc_ver = "unknown version";
  94. }
  95. snprintf(name, name_len, "ARC %s %s", arc_name, arc_ver);
  96. return name;
  97. }
  98. struct hs_template_t {
  99. const bool cache;
  100. const bool mmu;
  101. const bool dual_issue;
  102. const bool dsp;
  103. const char name[8];
  104. };
  105. static const struct hs_template_t hs_versions[] = {
  106. {false, false, false, false, "HS34"},
  107. {true, false, false, false, "HS36"},
  108. {true, true, false, false, "HS38"},
  109. {false, false, true, false, "HS44"},
  110. {true, false, true, false, "HS46"},
  111. {true, true, true, false, "HS48"},
  112. {false, false, true, true, "HS45D"},
  113. {true, false, true, true, "HS47D"},
  114. };
  115. const char *arc_hs_version(int arcver, char *name, int name_len)
  116. {
  117. const char *arc_name = "HS";
  118. const char *arc_ver;
  119. bool cache = ARC_FEATURE_EXISTS(ARC_BCR_IC_BUILD);
  120. bool dsp = ARC_FEATURE_EXISTS(ARC_AUX_DSP_BUILD);
  121. bool mmu = !!read_aux_reg(ARC_AUX_MMU_BCR);
  122. bool dual_issue = arcver == 0x54 ? true : false;
  123. int i;
  124. for (i = 0; i < sizeof(hs_versions) / sizeof(struct hs_template_t); i++) {
  125. if (hs_versions[i].cache == cache &&
  126. hs_versions[i].mmu == mmu &&
  127. hs_versions[i].dual_issue == dual_issue &&
  128. hs_versions[i].dsp == dsp) {
  129. arc_name = hs_versions[i].name;
  130. break;
  131. }
  132. }
  133. switch (arcver) {
  134. case 0x50:
  135. arc_ver = "v1.0";
  136. break;
  137. case 0x51:
  138. arc_ver = "v2.0";
  139. break;
  140. case 0x52:
  141. arc_ver = "v2.1c";
  142. break;
  143. case 0x53:
  144. arc_ver = "v3.0";
  145. break;
  146. case 0x54:
  147. arc_ver = "v4.0";
  148. break;
  149. default:
  150. arc_ver = "unknown version";
  151. }
  152. snprintf(name, name_len, "ARC %s %s", arc_name, arc_ver);
  153. return name;
  154. }
  155. const char *decode_identity(void)
  156. {
  157. #define MAX_CPU_NAME_LEN 64
  158. int arcver = read_aux_reg(ARC_AUX_IDENTITY) & 0xff;
  159. char *name = malloc(MAX_CPU_NAME_LEN);
  160. if (arcver >= 0x50)
  161. return arc_hs_version(arcver, name, MAX_CPU_NAME_LEN);
  162. else if (arcver >= 0x40)
  163. return arc_em_version(arcver, name, MAX_CPU_NAME_LEN);
  164. else if (arcver >= 0x30)
  165. return arc_700_version(arcver, name, MAX_CPU_NAME_LEN);
  166. else
  167. return "Unknown ARC core";
  168. }
  169. const char *decode_subsystem(void)
  170. {
  171. int subsys_type = read_aux_reg(ARC_AUX_SUBSYS_BUILD) & GENMASK(3, 0);
  172. switch (subsys_type) {
  173. case 0: return NULL;
  174. case 2: return "ARC Sensor & Control IP Subsystem";
  175. case 3: return "ARC Data Fusion IP Subsystem";
  176. case 4: return "ARC Secure Subsystem";
  177. default: return "Unknown subsystem";
  178. };
  179. }
  180. __weak int print_cpuinfo(void)
  181. {
  182. const char *subsys_name = decode_subsystem();
  183. char mhz[8];
  184. printf("CPU: %s at %s MHz\n", decode_identity(),
  185. strmhz(mhz, gd->cpu_clk));
  186. if (subsys_name)
  187. printf("Subsys:%s\n", subsys_name);
  188. return 0;
  189. }
  190. #endif /* CONFIG_DISPLAY_CPUINFO */