1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2013-2014, 2018 Synopsys, Inc. All rights reserved.
4  */
5 
6 #include <common.h>
7 #include <malloc.h>
8 #include <asm/arcregs.h>
9 #include <asm/cache.h>
10 
11 DECLARE_GLOBAL_DATA_PTR;
12 
arch_cpu_init(void)13 int arch_cpu_init(void)
14 {
15 	timer_init();
16 
17 	gd->cpu_clk = CONFIG_SYS_CLK_FREQ;
18 	gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
19 
20 	cache_init();
21 
22 	return 0;
23 }
24 
arch_early_init_r(void)25 int 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 }
31 
32 /* This is a dummy function on arc */
dram_init(void)33 int dram_init(void)
34 {
35 	return 0;
36 }
37 
38 #ifdef CONFIG_DISPLAY_CPUINFO
arc_700_version(int arcver,char * name,int name_len)39 const char *arc_700_version(int arcver, char *name, int name_len)
40 {
41 	const char *arc_ver;
42 
43 	switch (arcver) {
44 	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";
58 	}
59 
60 	snprintf(name, name_len, "ARC 700 %s", arc_ver);
61 
62 	return name;
63 }
64 
65 struct em_template_t {
66 	const bool cache;
67 	const bool dsp;
68 	const bool xymem;
69 	const char name[8];
70 };
71 
72 static 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 
arc_em_version(int arcver,char * name,int name_len)81 const 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 
90 	for (i = 0; i++ < sizeof(em_versions) / sizeof(struct em_template_t);) {
91 		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 
121 struct 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 
129 static 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 
arc_hs_version(int arcver,char * name,int name_len)140 const 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 
150 	for (i = 0; i++ < sizeof(hs_versions) / sizeof(struct hs_template_t);) {
151 		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 
decode_identity(void)185 const 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 
decode_subsystem(void)202 const 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 	};
213 }
214 
print_cpuinfo(void)215 __weak int print_cpuinfo(void)
216 {
217 	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 
226 	return 0;
227 }
228 #endif /* CONFIG_DISPLAY_CPUINFO */
229