blob: d66a8c867acdf722469077ad18983e76798da3e5 [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
Simon Glassd35f3382017-04-06 12:47:05 -060028/* This is a dummy function on arc */
29int dram_init(void)
30{
31 return 0;
32}
Alexey Brodkin9ab36962018-10-02 11:42:23 +030033
34#ifdef CONFIG_DISPLAY_CPUINFO
Alexey Brodkin166fb932018-11-27 09:46:57 +030035const char *arc_700_version(int arcver, char *name, int name_len)
Alexey Brodkin9ab36962018-10-02 11:42:23 +030036{
Alexey Brodkin166fb932018-11-27 09:46:57 +030037 const char *arc_ver;
38
39 switch (arcver) {
40 case 0x32:
41 arc_ver = "v4.4-4.5";
42 break;
43 case 0x33:
44 arc_ver = "v4.6-v4.9";
45 break;
46 case 0x34:
47 arc_ver = "v4.10";
48 break;
49 case 0x35:
50 arc_ver = "v4.11";
51 break;
52 default:
53 arc_ver = "unknown version";
54 }
55
56 snprintf(name, name_len, "ARC 700 %s", arc_ver);
57
58 return name;
59}
60
61struct em_template_t {
62 const bool cache;
63 const bool dsp;
64 const bool xymem;
65 const char name[8];
66};
67
68static const struct em_template_t em_versions[] = {
69 {false, false, false, "EM4"},
70 {true, false, false, "EM6"},
71 {false, true, false, "EM5D"},
72 {true, true, false, "EM7D"},
73 {false, true, true, "EM9D"},
74 {true, true, true, "EM11D"},
75};
76
77const char *arc_em_version(int arcver, char *name, int name_len)
78{
79 const char *arc_name = "EM";
80 const char *arc_ver;
81 bool cache = ARC_FEATURE_EXISTS(ARC_BCR_IC_BUILD);
82 bool dsp = ARC_FEATURE_EXISTS(ARC_AUX_DSP_BUILD);
83 bool xymem = ARC_FEATURE_EXISTS(ARC_AUX_XY_BUILD);
84 int i;
85
Alexey Brodkinb7e3a782019-01-22 19:33:59 +030086 for (i = 0; i < sizeof(em_versions) / sizeof(struct em_template_t); i++) {
Alexey Brodkin166fb932018-11-27 09:46:57 +030087 if (em_versions[i].cache == cache &&
88 em_versions[i].dsp == dsp &&
89 em_versions[i].xymem == xymem) {
90 arc_name = em_versions[i].name;
91 break;
92 }
93 }
Alexey Brodkin9ab36962018-10-02 11:42:23 +030094
95 switch (arcver) {
Alexey Brodkin166fb932018-11-27 09:46:57 +030096 case 0x41:
97 arc_ver = "v1.1a";
98 break;
99 case 0x42:
100 arc_ver = "v3.0";
101 break;
102 case 0x43:
103 arc_ver = "v4.0";
104 break;
105 case 0x44:
106 arc_ver = "v5.0";
107 break;
108 default:
109 arc_ver = "unknown version";
110 }
111
112 snprintf(name, name_len, "ARC %s %s", arc_name, arc_ver);
113
114 return name;
115}
116
117struct hs_template_t {
118 const bool cache;
119 const bool mmu;
120 const bool dual_issue;
121 const bool dsp;
122 const char name[8];
123};
124
125static const struct hs_template_t hs_versions[] = {
126 {false, false, false, false, "HS34"},
127 {true, false, false, false, "HS36"},
128 {true, true, false, false, "HS38"},
129 {false, false, true, false, "HS44"},
130 {true, false, true, false, "HS46"},
131 {true, true, true, false, "HS48"},
132 {false, false, true, true, "HS45D"},
133 {true, false, true, true, "HS47D"},
134};
Alexey Brodkin9ab36962018-10-02 11:42:23 +0300135
Alexey Brodkin166fb932018-11-27 09:46:57 +0300136const char *arc_hs_version(int arcver, char *name, int name_len)
137{
138 const char *arc_name = "HS";
139 const char *arc_ver;
140 bool cache = ARC_FEATURE_EXISTS(ARC_BCR_IC_BUILD);
141 bool dsp = ARC_FEATURE_EXISTS(ARC_AUX_DSP_BUILD);
142 bool mmu = !!read_aux_reg(ARC_AUX_MMU_BCR);
143 bool dual_issue = arcver == 0x54 ? true : false;
144 int i;
Alexey Brodkin9ab36962018-10-02 11:42:23 +0300145
Alexey Brodkinb7e3a782019-01-22 19:33:59 +0300146 for (i = 0; i < sizeof(hs_versions) / sizeof(struct hs_template_t); i++) {
Alexey Brodkin166fb932018-11-27 09:46:57 +0300147 if (hs_versions[i].cache == cache &&
148 hs_versions[i].mmu == mmu &&
149 hs_versions[i].dual_issue == dual_issue &&
150 hs_versions[i].dsp == dsp) {
151 arc_name = hs_versions[i].name;
152 break;
153 }
Alexey Brodkin9ab36962018-10-02 11:42:23 +0300154 }
Alexey Brodkin166fb932018-11-27 09:46:57 +0300155
156 switch (arcver) {
157 case 0x50:
158 arc_ver = "v1.0";
159 break;
160 case 0x51:
161 arc_ver = "v2.0";
162 break;
163 case 0x52:
164 arc_ver = "v2.1c";
165 break;
166 case 0x53:
167 arc_ver = "v3.0";
168 break;
169 case 0x54:
170 arc_ver = "v4.0";
171 break;
172 default:
173 arc_ver = "unknown version";
174 }
175
176 snprintf(name, name_len, "ARC %s %s", arc_name, arc_ver);
177
178 return name;
179}
180
181const char *decode_identity(void)
182{
183#define MAX_CPU_NAME_LEN 64
184
185 int arcver = read_aux_reg(ARC_AUX_IDENTITY) & 0xff;
186 char *name = malloc(MAX_CPU_NAME_LEN);
187
188 if (arcver >= 0x50)
189 return arc_hs_version(arcver, name, MAX_CPU_NAME_LEN);
190 else if (arcver >= 0x40)
191 return arc_em_version(arcver, name, MAX_CPU_NAME_LEN);
192 else if (arcver >= 0x30)
193 return arc_700_version(arcver, name, MAX_CPU_NAME_LEN);
194 else
195 return "Unknown ARC core";
196}
197
198const char *decode_subsystem(void)
199{
200 int subsys_type = read_aux_reg(ARC_AUX_SUBSYS_BUILD) & GENMASK(3, 0);
201
202 switch (subsys_type) {
203 case 0: return NULL;
204 case 2: return "ARC Sensor & Control IP Subsystem";
205 case 3: return "ARC Data Fusion IP Subsystem";
206 case 4: return "ARC Secure Subsystem";
207 default: return "Unknown subsystem";
208 };
Alexey Brodkin9ab36962018-10-02 11:42:23 +0300209}
210
Alexey Brodkine0fc13e2018-10-10 13:59:33 +0300211__weak int print_cpuinfo(void)
Alexey Brodkin9ab36962018-10-02 11:42:23 +0300212{
Alexey Brodkin166fb932018-11-27 09:46:57 +0300213 const char *subsys_name = decode_subsystem();
214 char mhz[8];
215
216 printf("CPU: %s at %s MHz\n", decode_identity(),
217 strmhz(mhz, gd->cpu_clk));
218
219 if (subsys_name)
220 printf("Subsys:%s\n", subsys_name);
221
Alexey Brodkin9ab36962018-10-02 11:42:23 +0300222 return 0;
223}
224#endif /* CONFIG_DISPLAY_CPUINFO */