blob: 01cca95d5b1854cd07029fd978b3cdc8f67beffa [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>
Alexey Brodkin2f16ac92014-02-04 12:56:14 +04008#include <asm/arcregs.h>
9#include <asm/cache.h>
10
11DECLARE_GLOBAL_DATA_PTR;
12
13int arch_cpu_init(void)
14{
Alexey Brodkin2f16ac92014-02-04 12:56:14 +040015 timer_init();
16
Alexey Brodkin2f16ac92014-02-04 12:56:14 +040017 gd->cpu_clk = CONFIG_SYS_CLK_FREQ;
18 gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
19
Alexey Brodkinef639e62015-05-18 16:56:26 +030020 cache_init();
21
Alexey Brodkin2f16ac92014-02-04 12:56:14 +040022 return 0;
23}
24
25int 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}
Simon Glassf1683aa2017-04-06 12:47:05 -060031
32/* This is a dummy function on arc */
33int dram_init(void)
34{
35 return 0;
36}
Alexey Brodkin7fe46b92018-10-02 11:42:23 +030037
38#ifdef CONFIG_DISPLAY_CPUINFO
Alexey Brodkin85e529f2018-11-27 09:46:57 +030039const char *arc_700_version(int arcver, char *name, int name_len)
Alexey Brodkin7fe46b92018-10-02 11:42:23 +030040{
Alexey Brodkin85e529f2018-11-27 09:46:57 +030041 const char *arc_ver;
Alexey Brodkin7fe46b92018-10-02 11:42:23 +030042
43 switch (arcver) {
Alexey Brodkin85e529f2018-11-27 09:46:57 +030044 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";
Alexey Brodkin7fe46b92018-10-02 11:42:23 +030058 }
Alexey Brodkin85e529f2018-11-27 09:46:57 +030059
60 snprintf(name, name_len, "ARC 700 %s", arc_ver);
61
62 return name;
63}
64
65struct em_template_t {
66 const bool cache;
67 const bool dsp;
68 const bool xymem;
69 const char name[8];
70};
71
72static 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
81const 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
Alexey Brodkin7181a6d2019-01-22 19:33:59 +030090 for (i = 0; i < sizeof(em_versions) / sizeof(struct em_template_t); i++) {
Alexey Brodkin85e529f2018-11-27 09:46:57 +030091 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
121struct 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
129static 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
140const 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
Alexey Brodkin7181a6d2019-01-22 19:33:59 +0300150 for (i = 0; i < sizeof(hs_versions) / sizeof(struct hs_template_t); i++) {
Alexey Brodkin85e529f2018-11-27 09:46:57 +0300151 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
185const 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
202const 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 };
Alexey Brodkin7fe46b92018-10-02 11:42:23 +0300213}
214
Alexey Brodkinba9f56f2018-10-10 13:59:33 +0300215__weak int print_cpuinfo(void)
Alexey Brodkin7fe46b92018-10-02 11:42:23 +0300216{
Alexey Brodkin85e529f2018-11-27 09:46:57 +0300217 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
Alexey Brodkin7fe46b92018-10-02 11:42:23 +0300226 return 0;
227}
228#endif /* CONFIG_DISPLAY_CPUINFO */