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