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