blob: 156785796183c428e8d51556b5867972133a8ed6 [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>
Tom Rini8c70baa2021-12-14 13:36:40 -05007#include <clock_legacy.h>
Simon Glass97589732020-05-10 11:40:02 -06008#include <init.h>
Alexey Brodkin166fb932018-11-27 09:46:57 +03009#include <malloc.h>
Simon Glassf5c208d2019-11-14 12:57:20 -070010#include <vsprintf.h>
Alexey Brodkin3a59d912014-02-04 12:56:14 +040011#include <asm/arcregs.h>
12#include <asm/cache.h>
Simon Glass3ba929a2020-10-30 21:38:53 -060013#include <asm/global_data.h>
Simon Glass4dcacfc2020-05-10 11:40:13 -060014#include <linux/bitops.h>
Alexey Brodkin3a59d912014-02-04 12:56:14 +040015
16DECLARE_GLOBAL_DATA_PTR;
17
18int arch_cpu_init(void)
19{
Alexey Brodkin3a59d912014-02-04 12:56:14 +040020 timer_init();
21
Tom Rini8c70baa2021-12-14 13:36:40 -050022 gd->cpu_clk = get_board_sys_clk();
Tom Rinibb4dd962022-11-16 13:10:37 -050023 gd->ram_size = CFG_SYS_SDRAM_SIZE;
Alexey Brodkin3a59d912014-02-04 12:56:14 +040024
Alexey Brodkin9f916ee2015-05-18 16:56:26 +030025 cache_init();
26
Alexey Brodkin3a59d912014-02-04 12:56:14 +040027 return 0;
28}
29
Simon Glassd35f3382017-04-06 12:47:05 -060030/* This is a dummy function on arc */
31int dram_init(void)
32{
33 return 0;
34}
Alexey Brodkin9ab36962018-10-02 11:42:23 +030035
36#ifdef CONFIG_DISPLAY_CPUINFO
Alexey Brodkin166fb932018-11-27 09:46:57 +030037const char *arc_700_version(int arcver, char *name, int name_len)
Alexey Brodkin9ab36962018-10-02 11:42:23 +030038{
Alexey Brodkin166fb932018-11-27 09:46:57 +030039 const char *arc_ver;
40
41 switch (arcver) {
42 case 0x32:
43 arc_ver = "v4.4-4.5";
44 break;
45 case 0x33:
46 arc_ver = "v4.6-v4.9";
47 break;
48 case 0x34:
49 arc_ver = "v4.10";
50 break;
51 case 0x35:
52 arc_ver = "v4.11";
53 break;
54 default:
55 arc_ver = "unknown version";
56 }
57
58 snprintf(name, name_len, "ARC 700 %s", arc_ver);
59
60 return name;
61}
62
63struct em_template_t {
64 const bool cache;
65 const bool dsp;
66 const bool xymem;
67 const char name[8];
68};
69
70static const struct em_template_t em_versions[] = {
71 {false, false, false, "EM4"},
72 {true, false, false, "EM6"},
73 {false, true, false, "EM5D"},
74 {true, true, false, "EM7D"},
75 {false, true, true, "EM9D"},
76 {true, true, true, "EM11D"},
77};
78
79const char *arc_em_version(int arcver, char *name, int name_len)
80{
81 const char *arc_name = "EM";
82 const char *arc_ver;
83 bool cache = ARC_FEATURE_EXISTS(ARC_BCR_IC_BUILD);
84 bool dsp = ARC_FEATURE_EXISTS(ARC_AUX_DSP_BUILD);
85 bool xymem = ARC_FEATURE_EXISTS(ARC_AUX_XY_BUILD);
86 int i;
87
Alexey Brodkinb7e3a782019-01-22 19:33:59 +030088 for (i = 0; i < sizeof(em_versions) / sizeof(struct em_template_t); i++) {
Alexey Brodkin166fb932018-11-27 09:46:57 +030089 if (em_versions[i].cache == cache &&
90 em_versions[i].dsp == dsp &&
91 em_versions[i].xymem == xymem) {
92 arc_name = em_versions[i].name;
93 break;
94 }
95 }
Alexey Brodkin9ab36962018-10-02 11:42:23 +030096
97 switch (arcver) {
Alexey Brodkin166fb932018-11-27 09:46:57 +030098 case 0x41:
99 arc_ver = "v1.1a";
100 break;
101 case 0x42:
102 arc_ver = "v3.0";
103 break;
104 case 0x43:
105 arc_ver = "v4.0";
106 break;
107 case 0x44:
108 arc_ver = "v5.0";
109 break;
110 default:
111 arc_ver = "unknown version";
112 }
113
114 snprintf(name, name_len, "ARC %s %s", arc_name, arc_ver);
115
116 return name;
117}
118
119struct hs_template_t {
120 const bool cache;
121 const bool mmu;
122 const bool dual_issue;
123 const bool dsp;
124 const char name[8];
125};
126
127static const struct hs_template_t hs_versions[] = {
128 {false, false, false, false, "HS34"},
129 {true, false, false, false, "HS36"},
130 {true, true, false, false, "HS38"},
131 {false, false, true, false, "HS44"},
132 {true, false, true, false, "HS46"},
133 {true, true, true, false, "HS48"},
134 {false, false, true, true, "HS45D"},
135 {true, false, true, true, "HS47D"},
136};
Alexey Brodkin9ab36962018-10-02 11:42:23 +0300137
Alexey Brodkin166fb932018-11-27 09:46:57 +0300138const char *arc_hs_version(int arcver, char *name, int name_len)
139{
140 const char *arc_name = "HS";
141 const char *arc_ver;
142 bool cache = ARC_FEATURE_EXISTS(ARC_BCR_IC_BUILD);
143 bool dsp = ARC_FEATURE_EXISTS(ARC_AUX_DSP_BUILD);
144 bool mmu = !!read_aux_reg(ARC_AUX_MMU_BCR);
145 bool dual_issue = arcver == 0x54 ? true : false;
146 int i;
Alexey Brodkin9ab36962018-10-02 11:42:23 +0300147
Alexey Brodkinb7e3a782019-01-22 19:33:59 +0300148 for (i = 0; i < sizeof(hs_versions) / sizeof(struct hs_template_t); i++) {
Alexey Brodkin166fb932018-11-27 09:46:57 +0300149 if (hs_versions[i].cache == cache &&
150 hs_versions[i].mmu == mmu &&
151 hs_versions[i].dual_issue == dual_issue &&
152 hs_versions[i].dsp == dsp) {
153 arc_name = hs_versions[i].name;
154 break;
155 }
Alexey Brodkin9ab36962018-10-02 11:42:23 +0300156 }
Alexey Brodkin166fb932018-11-27 09:46:57 +0300157
158 switch (arcver) {
159 case 0x50:
160 arc_ver = "v1.0";
161 break;
162 case 0x51:
163 arc_ver = "v2.0";
164 break;
165 case 0x52:
166 arc_ver = "v2.1c";
167 break;
168 case 0x53:
169 arc_ver = "v3.0";
170 break;
171 case 0x54:
172 arc_ver = "v4.0";
173 break;
174 default:
175 arc_ver = "unknown version";
176 }
177
178 snprintf(name, name_len, "ARC %s %s", arc_name, arc_ver);
179
180 return name;
181}
182
183const char *decode_identity(void)
184{
185#define MAX_CPU_NAME_LEN 64
186
187 int arcver = read_aux_reg(ARC_AUX_IDENTITY) & 0xff;
188 char *name = malloc(MAX_CPU_NAME_LEN);
189
190 if (arcver >= 0x50)
191 return arc_hs_version(arcver, name, MAX_CPU_NAME_LEN);
192 else if (arcver >= 0x40)
193 return arc_em_version(arcver, name, MAX_CPU_NAME_LEN);
194 else if (arcver >= 0x30)
195 return arc_700_version(arcver, name, MAX_CPU_NAME_LEN);
196 else
197 return "Unknown ARC core";
198}
199
200const char *decode_subsystem(void)
201{
202 int subsys_type = read_aux_reg(ARC_AUX_SUBSYS_BUILD) & GENMASK(3, 0);
203
204 switch (subsys_type) {
205 case 0: return NULL;
206 case 2: return "ARC Sensor & Control IP Subsystem";
207 case 3: return "ARC Data Fusion IP Subsystem";
208 case 4: return "ARC Secure Subsystem";
209 default: return "Unknown subsystem";
210 };
Alexey Brodkin9ab36962018-10-02 11:42:23 +0300211}
212
Alexey Brodkine0fc13e2018-10-10 13:59:33 +0300213__weak int print_cpuinfo(void)
Alexey Brodkin9ab36962018-10-02 11:42:23 +0300214{
Alexey Brodkin166fb932018-11-27 09:46:57 +0300215 const char *subsys_name = decode_subsystem();
216 char mhz[8];
217
218 printf("CPU: %s at %s MHz\n", decode_identity(),
219 strmhz(mhz, gd->cpu_clk));
220
221 if (subsys_name)
222 printf("Subsys:%s\n", subsys_name);
223
Alexey Brodkin9ab36962018-10-02 11:42:23 +0300224 return 0;
225}
226#endif /* CONFIG_DISPLAY_CPUINFO */