blob: 83246550ec1250ecac153d131939b8f5491ad8b5 [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Alexey Brodkin2f16ac92014-02-04 12:56:14 +04002/*
Alexey Brodkin7fe46b92018-10-02 11:42:23 +03003 * Copyright (C) 2013-2014, 2018 Synopsys, Inc. All rights reserved.
Alexey Brodkin2f16ac92014-02-04 12:56:14 +04004 */
5
6#include <common.h>
Alexey Brodkin85e529f2018-11-27 09:46:57 +03007#include <malloc.h>
Simon Glass2189d5f2019-11-14 12:57:20 -07008#include <vsprintf.h>
Alexey Brodkin2f16ac92014-02-04 12:56:14 +04009#include <asm/arcregs.h>
10#include <asm/cache.h>
11
12DECLARE_GLOBAL_DATA_PTR;
13
14int arch_cpu_init(void)
15{
Alexey Brodkin2f16ac92014-02-04 12:56:14 +040016 timer_init();
17
Alexey Brodkin2f16ac92014-02-04 12:56:14 +040018 gd->cpu_clk = CONFIG_SYS_CLK_FREQ;
19 gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
20
Alexey Brodkinef639e62015-05-18 16:56:26 +030021 cache_init();
22
Alexey Brodkin2f16ac92014-02-04 12:56:14 +040023 return 0;
24}
25
26int 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}
Simon Glassf1683aa2017-04-06 12:47:05 -060032
33/* This is a dummy function on arc */
34int dram_init(void)
35{
36 return 0;
37}
Alexey Brodkin7fe46b92018-10-02 11:42:23 +030038
39#ifdef CONFIG_DISPLAY_CPUINFO
Alexey Brodkin85e529f2018-11-27 09:46:57 +030040const char *arc_700_version(int arcver, char *name, int name_len)
Alexey Brodkin7fe46b92018-10-02 11:42:23 +030041{
Alexey Brodkin85e529f2018-11-27 09:46:57 +030042 const char *arc_ver;
Alexey Brodkin7fe46b92018-10-02 11:42:23 +030043
44 switch (arcver) {
Alexey Brodkin85e529f2018-11-27 09:46:57 +030045 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";
Alexey Brodkin7fe46b92018-10-02 11:42:23 +030059 }
Alexey Brodkin85e529f2018-11-27 09:46:57 +030060
61 snprintf(name, name_len, "ARC 700 %s", arc_ver);
62
63 return name;
64}
65
66struct em_template_t {
67 const bool cache;
68 const bool dsp;
69 const bool xymem;
70 const char name[8];
71};
72
73static 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
82const 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
Alexey Brodkin7181a6d2019-01-22 19:33:59 +030091 for (i = 0; i < sizeof(em_versions) / sizeof(struct em_template_t); i++) {
Alexey Brodkin85e529f2018-11-27 09:46:57 +030092 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
122struct 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
130static 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
141const 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
Alexey Brodkin7181a6d2019-01-22 19:33:59 +0300151 for (i = 0; i < sizeof(hs_versions) / sizeof(struct hs_template_t); i++) {
Alexey Brodkin85e529f2018-11-27 09:46:57 +0300152 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
186const 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
203const 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 };
Alexey Brodkin7fe46b92018-10-02 11:42:23 +0300214}
215
Alexey Brodkinba9f56f2018-10-10 13:59:33 +0300216__weak int print_cpuinfo(void)
Alexey Brodkin7fe46b92018-10-02 11:42:23 +0300217{
Alexey Brodkin85e529f2018-11-27 09:46:57 +0300218 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
Alexey Brodkin7fe46b92018-10-02 11:42:23 +0300227 return 0;
228}
229#endif /* CONFIG_DISPLAY_CPUINFO */