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