xref: /rk3399_ARM-atf/plat/xilinx/zynqmp/aarch64/zynqmp_common.c (revision ff2743e544f0f82381ebb9dff8f14eacb837d2e0)
1 /*
2  * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <debug.h>
8 #include <generic_delay_timer.h>
9 #include <mmio.h>
10 #include <platform.h>
11 #include <stdbool.h>
12 #include <string.h>
13 #include <xlat_tables.h>
14 #include "../zynqmp_private.h"
15 #include "pm_api_sys.h"
16 
17 /*
18  * Table of regions to map using the MMU.
19  * This doesn't include TZRAM as the 'mem_layout' argument passed to
20  * configure_mmu_elx() will give the available subset of that,
21  */
22 const mmap_region_t plat_arm_mmap[] = {
23 	{ DEVICE0_BASE, DEVICE0_BASE, DEVICE0_SIZE, MT_DEVICE | MT_RW | MT_SECURE },
24 	{ DEVICE1_BASE, DEVICE1_BASE, DEVICE1_SIZE, MT_DEVICE | MT_RW | MT_SECURE },
25 	{ CRF_APB_BASE, CRF_APB_BASE, CRF_APB_SIZE, MT_DEVICE | MT_RW | MT_SECURE },
26 	{0}
27 };
28 
29 static unsigned int zynqmp_get_silicon_ver(void)
30 {
31 	static unsigned int ver;
32 
33 	if (!ver) {
34 		ver = mmio_read_32(ZYNQMP_CSU_BASEADDR +
35 				   ZYNQMP_CSU_VERSION_OFFSET);
36 		ver &= ZYNQMP_SILICON_VER_MASK;
37 		ver >>= ZYNQMP_SILICON_VER_SHIFT;
38 	}
39 
40 	return ver;
41 }
42 
43 unsigned int zynqmp_get_uart_clk(void)
44 {
45 	unsigned int ver = zynqmp_get_silicon_ver();
46 
47 	switch (ver) {
48 	case ZYNQMP_CSU_VERSION_VELOCE:
49 		return 48000;
50 	case ZYNQMP_CSU_VERSION_EP108:
51 		return 25000000;
52 	case ZYNQMP_CSU_VERSION_QEMU:
53 		return 133000000;
54 	default:
55 		/* Do nothing in default case */
56 		break;
57 	}
58 
59 	return 100000000;
60 }
61 
62 #if LOG_LEVEL >= LOG_LEVEL_NOTICE
63 static const struct {
64 	unsigned int id;
65 	unsigned int ver;
66 	char *name;
67 	bool evexists;
68 } zynqmp_devices[] = {
69 	{
70 		.id = 0x10,
71 		.name = "3EG",
72 	},
73 	{
74 		.id = 0x10,
75 		.ver = 0x2c,
76 		.name = "3CG",
77 	},
78 	{
79 		.id = 0x11,
80 		.name = "2EG",
81 	},
82 	{
83 		.id = 0x11,
84 		.ver = 0x2c,
85 		.name = "2CG",
86 	},
87 	{
88 		.id = 0x20,
89 		.name = "5EV",
90 		.evexists = true,
91 	},
92 	{
93 		.id = 0x20,
94 		.ver = 0x100,
95 		.name = "5EG",
96 		.evexists = true,
97 	},
98 	{
99 		.id = 0x20,
100 		.ver = 0x12c,
101 		.name = "5CG",
102 	},
103 	{
104 		.id = 0x21,
105 		.name = "4EV",
106 		.evexists = true,
107 	},
108 	{
109 		.id = 0x21,
110 		.ver = 0x100,
111 		.name = "4EG",
112 		.evexists = true,
113 	},
114 	{
115 		.id = 0x21,
116 		.ver = 0x12c,
117 		.name = "4CG",
118 	},
119 	{
120 		.id = 0x30,
121 		.name = "7EV",
122 		.evexists = true,
123 	},
124 	{
125 		.id = 0x30,
126 		.ver = 0x100,
127 		.name = "7EG",
128 		.evexists = true,
129 	},
130 	{
131 		.id = 0x30,
132 		.ver = 0x12c,
133 		.name = "7CG",
134 	},
135 	{
136 		.id = 0x38,
137 		.name = "9EG",
138 	},
139 	{
140 		.id = 0x38,
141 		.ver = 0x2c,
142 		.name = "9CG",
143 	},
144 	{
145 		.id = 0x39,
146 		.name = "6EG",
147 	},
148 	{
149 		.id = 0x39,
150 		.ver = 0x2c,
151 		.name = "6CG",
152 	},
153 	{
154 		.id = 0x40,
155 		.name = "11EG",
156 	},
157 	{ /* For testing purpose only */
158 		.id = 0x50,
159 		.ver = 0x2c,
160 		.name = "15CG",
161 	},
162 	{
163 		.id = 0x50,
164 		.name = "15EG",
165 	},
166 	{
167 		.id = 0x58,
168 		.name = "19EG",
169 	},
170 	{
171 		.id = 0x59,
172 		.name = "17EG",
173 	},
174 	{
175 		.id = 0x60,
176 		.name = "28DR",
177 	},
178 	{
179 		.id = 0x61,
180 		.name = "21DR",
181 	},
182 	{
183 		.id = 0x62,
184 		.name = "29DR",
185 	},
186 	{
187 		.id = 0x63,
188 		.name = "23DR",
189 	},
190 	{
191 		.id = 0x64,
192 		.name = "27DR",
193 	},
194 	{
195 		.id = 0x65,
196 		.name = "25DR",
197 	},
198 };
199 
200 #define ZYNQMP_PL_STATUS_BIT	9
201 #define ZYNQMP_PL_STATUS_MASK	BIT(ZYNQMP_PL_STATUS_BIT)
202 #define ZYNQMP_CSU_VERSION_MASK	~(ZYNQMP_PL_STATUS_MASK)
203 
204 static char *zynqmp_get_silicon_idcode_name(void)
205 {
206 	uint32_t id, ver, chipid[2];
207 	size_t i, j, len;
208 	enum pm_ret_status ret;
209 	const char *name = "EG/EV";
210 
211 	ret = pm_get_chipid(chipid);
212 	if (ret)
213 		return "UNKN";
214 
215 	id = chipid[0] & (ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK |
216 			  ZYNQMP_CSU_IDCODE_SVD_MASK);
217 	id >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT;
218 	ver = chipid[1] >> ZYNQMP_EFUSE_IPDISABLE_SHIFT;
219 
220 	for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
221 		if (zynqmp_devices[i].id == id &&
222 		    zynqmp_devices[i].ver == (ver & ZYNQMP_CSU_VERSION_MASK))
223 			break;
224 	}
225 
226 	if (i >= ARRAY_SIZE(zynqmp_devices))
227 		return "UNKN";
228 
229 	if (!zynqmp_devices[i].evexists)
230 		return zynqmp_devices[i].name;
231 
232 	if (ver & ZYNQMP_PL_STATUS_MASK)
233 		return zynqmp_devices[i].name;
234 
235 	len = strlen(zynqmp_devices[i].name) - 2;
236 	for (j = 0; j < strlen(name); j++) {
237 		zynqmp_devices[i].name[len] = name[j];
238 		len++;
239 	}
240 	zynqmp_devices[i].name[len] = '\0';
241 
242 	return zynqmp_devices[i].name;
243 }
244 
245 static unsigned int zynqmp_get_rtl_ver(void)
246 {
247 	uint32_t ver;
248 
249 	ver = mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_VERSION_OFFSET);
250 	ver &= ZYNQMP_RTL_VER_MASK;
251 	ver >>= ZYNQMP_RTL_VER_SHIFT;
252 
253 	return ver;
254 }
255 
256 static char *zynqmp_print_silicon_idcode(void)
257 {
258 	uint32_t id, maskid, tmp;
259 
260 	id = mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_IDCODE_OFFSET);
261 
262 	tmp = id;
263 	tmp &= ZYNQMP_CSU_IDCODE_XILINX_ID_MASK |
264 	       ZYNQMP_CSU_IDCODE_FAMILY_MASK;
265 	maskid = ZYNQMP_CSU_IDCODE_XILINX_ID << ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT |
266 		 ZYNQMP_CSU_IDCODE_FAMILY << ZYNQMP_CSU_IDCODE_FAMILY_SHIFT;
267 	if (tmp != maskid) {
268 		ERROR("Incorrect XILINX IDCODE 0x%x, maskid 0x%x\n", id, maskid);
269 		return "UNKN";
270 	}
271 	VERBOSE("Xilinx IDCODE 0x%x\n", id);
272 	return zynqmp_get_silicon_idcode_name();
273 }
274 
275 static unsigned int zynqmp_get_ps_ver(void)
276 {
277 	uint32_t ver = mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_VERSION_OFFSET);
278 
279 	ver &= ZYNQMP_PS_VER_MASK;
280 	ver >>= ZYNQMP_PS_VER_SHIFT;
281 
282 	return ver + 1;
283 }
284 
285 static void zynqmp_print_platform_name(void)
286 {
287 	unsigned int ver = zynqmp_get_silicon_ver();
288 	unsigned int rtl = zynqmp_get_rtl_ver();
289 	char *label = "Unknown";
290 
291 	switch (ver) {
292 	case ZYNQMP_CSU_VERSION_VELOCE:
293 		label = "VELOCE";
294 		break;
295 	case ZYNQMP_CSU_VERSION_EP108:
296 		label = "EP108";
297 		break;
298 	case ZYNQMP_CSU_VERSION_QEMU:
299 		label = "QEMU";
300 		break;
301 	case ZYNQMP_CSU_VERSION_SILICON:
302 		label = "silicon";
303 		break;
304 	default:
305 		/* Do nothing in default case */
306 		break;
307 	}
308 
309 	NOTICE("ATF running on XCZU%s/%s v%d/RTL%d.%d at 0x%x\n",
310 	       zynqmp_print_silicon_idcode(), label, zynqmp_get_ps_ver(),
311 	       (rtl & 0xf0) >> 4, rtl & 0xf, BL31_BASE);
312 }
313 #else
314 static inline void zynqmp_print_platform_name(void) { }
315 #endif
316 
317 unsigned int zynqmp_get_bootmode(void)
318 {
319 	uint32_t r;
320 	unsigned int ret;
321 
322 	ret = pm_mmio_read(CRL_APB_BOOT_MODE_USER, &r);
323 
324 	if (ret != PM_RET_SUCCESS)
325 		r = mmio_read_32(CRL_APB_BOOT_MODE_USER);
326 
327 	return r & CRL_APB_BOOT_MODE_MASK;
328 }
329 
330 void zynqmp_config_setup(void)
331 {
332 	zynqmp_print_platform_name();
333 	generic_delay_timer_init();
334 }
335 
336 unsigned int plat_get_syscnt_freq2(void)
337 {
338 	unsigned int ver = zynqmp_get_silicon_ver();
339 
340 	switch (ver) {
341 	case ZYNQMP_CSU_VERSION_VELOCE:
342 		return 10000;
343 	case ZYNQMP_CSU_VERSION_EP108:
344 		return 4000000;
345 	case ZYNQMP_CSU_VERSION_QEMU:
346 		return 50000000;
347 	default:
348 		/* Do nothing in default case */
349 		break;
350 	}
351 
352 	return mmio_read_32(IOU_SCNTRS_BASEFREQ);
353 }
354