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