blob: 27b5832a0c9652adab69cabf97d57c034e9e5869 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Alexey Brodkin3a59d912014-02-04 12:56:14 +04002/*
Alexey Brodkin9ab36962018-10-02 11:42:23 +03003 * Copyright (C) 2013-2014, 2018 Synopsys, Inc. All rights reserved.
Alexey Brodkin3a59d912014-02-04 12:56:14 +04004 */
5
6#include <common.h>
Simon Glass97589732020-05-10 11:40:02 -06007#include <init.h>
Alexey Brodkin166fb932018-11-27 09:46:57 +03008#include <malloc.h>
Simon Glassf5c208d2019-11-14 12:57:20 -07009#include <vsprintf.h>
Alexey Brodkin3a59d912014-02-04 12:56:14 +040010#include <asm/arcregs.h>
11#include <asm/cache.h>
Simon Glass4dcacfc2020-05-10 11:40:13 -060012#include <linux/bitops.h>
Alexey Brodkin3a59d912014-02-04 12:56:14 +040013
14DECLARE_GLOBAL_DATA_PTR;
15
16int arch_cpu_init(void)
17{
Alexey Brodkin3a59d912014-02-04 12:56:14 +040018 timer_init();
19
Alexey Brodkin3a59d912014-02-04 12:56:14 +040020 gd->cpu_clk = CONFIG_SYS_CLK_FREQ;
21 gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
22
Alexey Brodkin9f916ee2015-05-18 16:56:26 +030023 cache_init();
24
Alexey Brodkin3a59d912014-02-04 12:56:14 +040025 return 0;
26}
27
28int 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}
Simon Glassd35f3382017-04-06 12:47:05 -060034
35/* This is a dummy function on arc */
36int dram_init(void)
37{
38 return 0;
39}
Alexey Brodkin9ab36962018-10-02 11:42:23 +030040
41#ifdef CONFIG_DISPLAY_CPUINFO
Alexey Brodkin166fb932018-11-27 09:46:57 +030042const char *arc_700_version(int arcver, char *name, int name_len)
Alexey Brodkin9ab36962018-10-02 11:42:23 +030043{
Alexey Brodkin166fb932018-11-27 09:46:57 +030044 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
68struct em_template_t {
69 const bool cache;
70 const bool dsp;
71 const bool xymem;
72 const char name[8];
73};
74
75static 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
84const 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
Alexey Brodkinb7e3a782019-01-22 19:33:59 +030093 for (i = 0; i < sizeof(em_versions) / sizeof(struct em_template_t); i++) {
Alexey Brodkin166fb932018-11-27 09:46:57 +030094 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 }
Alexey Brodkin9ab36962018-10-02 11:42:23 +0300101
102 switch (arcver) {
Alexey Brodkin166fb932018-11-27 09:46:57 +0300103 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
124struct 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
132static 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};
Alexey Brodkin9ab36962018-10-02 11:42:23 +0300142
Alexey Brodkin166fb932018-11-27 09:46:57 +0300143const 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;
Alexey Brodkin9ab36962018-10-02 11:42:23 +0300152
Alexey Brodkinb7e3a782019-01-22 19:33:59 +0300153 for (i = 0; i < sizeof(hs_versions) / sizeof(struct hs_template_t); i++) {
Alexey Brodkin166fb932018-11-27 09:46:57 +0300154 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 }
Alexey Brodkin9ab36962018-10-02 11:42:23 +0300161 }
Alexey Brodkin166fb932018-11-27 09:46:57 +0300162
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
188const 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
205const 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 };
Alexey Brodkin9ab36962018-10-02 11:42:23 +0300216}
217
Alexey Brodkine0fc13e2018-10-10 13:59:33 +0300218__weak int print_cpuinfo(void)
Alexey Brodkin9ab36962018-10-02 11:42:23 +0300219{
Alexey Brodkin166fb932018-11-27 09:46:57 +0300220 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
Alexey Brodkin9ab36962018-10-02 11:42:23 +0300229 return 0;
230}
231#endif /* CONFIG_DISPLAY_CPUINFO */