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