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