xref: /rk3399_ARM-atf/plat/xilinx/zynqmp/aarch64/zynqmp_common.c (revision 61f72a34250d063da67f4fc2b0eb8c3fda3376be)
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 	const char *name = "EG/EV";
209 
210 #ifdef IMAGE_BL32
211 	/*
212 	 * For BL32, get the chip id info directly by reading corresponding
213 	 * registers instead of making pm call. This has limitation
214 	 * that these registers should be configured to have access
215 	 * from APU which is default case.
216 	 */
217 	chipid[0] = mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_IDCODE_OFFSET);
218 	chipid[1] = mmio_read_32(EFUSE_BASEADDR + EFUSE_IPDISABLE_OFFSET);
219 #else
220 	if (pm_get_chipid(chipid) != PM_RET_SUCCESS)
221 		return "UNKN";
222 #endif
223 
224 	id = chipid[0] & (ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK |
225 			  ZYNQMP_CSU_IDCODE_SVD_MASK);
226 	id >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT;
227 	ver = chipid[1] >> ZYNQMP_EFUSE_IPDISABLE_SHIFT;
228 
229 	for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
230 		if (zynqmp_devices[i].id == id &&
231 		    zynqmp_devices[i].ver == (ver & ZYNQMP_CSU_VERSION_MASK))
232 			break;
233 	}
234 
235 	if (i >= ARRAY_SIZE(zynqmp_devices))
236 		return "UNKN";
237 
238 	if (!zynqmp_devices[i].evexists)
239 		return zynqmp_devices[i].name;
240 
241 	if (ver & ZYNQMP_PL_STATUS_MASK)
242 		return zynqmp_devices[i].name;
243 
244 	len = strlen(zynqmp_devices[i].name) - 2;
245 	for (j = 0; j < strlen(name); j++) {
246 		zynqmp_devices[i].name[len] = name[j];
247 		len++;
248 	}
249 	zynqmp_devices[i].name[len] = '\0';
250 
251 	return zynqmp_devices[i].name;
252 }
253 
254 static unsigned int zynqmp_get_rtl_ver(void)
255 {
256 	uint32_t ver;
257 
258 	ver = mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_VERSION_OFFSET);
259 	ver &= ZYNQMP_RTL_VER_MASK;
260 	ver >>= ZYNQMP_RTL_VER_SHIFT;
261 
262 	return ver;
263 }
264 
265 static char *zynqmp_print_silicon_idcode(void)
266 {
267 	uint32_t id, maskid, tmp;
268 
269 	id = mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_IDCODE_OFFSET);
270 
271 	tmp = id;
272 	tmp &= ZYNQMP_CSU_IDCODE_XILINX_ID_MASK |
273 	       ZYNQMP_CSU_IDCODE_FAMILY_MASK;
274 	maskid = ZYNQMP_CSU_IDCODE_XILINX_ID << ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT |
275 		 ZYNQMP_CSU_IDCODE_FAMILY << ZYNQMP_CSU_IDCODE_FAMILY_SHIFT;
276 	if (tmp != maskid) {
277 		ERROR("Incorrect XILINX IDCODE 0x%x, maskid 0x%x\n", id, maskid);
278 		return "UNKN";
279 	}
280 	VERBOSE("Xilinx IDCODE 0x%x\n", id);
281 	return zynqmp_get_silicon_idcode_name();
282 }
283 
284 static unsigned int zynqmp_get_ps_ver(void)
285 {
286 	uint32_t ver = mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_VERSION_OFFSET);
287 
288 	ver &= ZYNQMP_PS_VER_MASK;
289 	ver >>= ZYNQMP_PS_VER_SHIFT;
290 
291 	return ver + 1;
292 }
293 
294 static void zynqmp_print_platform_name(void)
295 {
296 	unsigned int ver = zynqmp_get_silicon_ver();
297 	unsigned int rtl = zynqmp_get_rtl_ver();
298 	char *label = "Unknown";
299 
300 	switch (ver) {
301 	case ZYNQMP_CSU_VERSION_VELOCE:
302 		label = "VELOCE";
303 		break;
304 	case ZYNQMP_CSU_VERSION_EP108:
305 		label = "EP108";
306 		break;
307 	case ZYNQMP_CSU_VERSION_QEMU:
308 		label = "QEMU";
309 		break;
310 	case ZYNQMP_CSU_VERSION_SILICON:
311 		label = "silicon";
312 		break;
313 	default:
314 		/* Do nothing in default case */
315 		break;
316 	}
317 
318 	NOTICE("ATF running on XCZU%s/%s v%d/RTL%d.%d at 0x%x\n",
319 	       zynqmp_print_silicon_idcode(), label, zynqmp_get_ps_ver(),
320 	       (rtl & 0xf0) >> 4, rtl & 0xf, BL31_BASE);
321 }
322 #else
323 static inline void zynqmp_print_platform_name(void) { }
324 #endif
325 
326 unsigned int zynqmp_get_bootmode(void)
327 {
328 	uint32_t r;
329 	unsigned int ret;
330 
331 	ret = pm_mmio_read(CRL_APB_BOOT_MODE_USER, &r);
332 
333 	if (ret != PM_RET_SUCCESS)
334 		r = mmio_read_32(CRL_APB_BOOT_MODE_USER);
335 
336 	return r & CRL_APB_BOOT_MODE_MASK;
337 }
338 
339 void zynqmp_config_setup(void)
340 {
341 	zynqmp_print_platform_name();
342 	generic_delay_timer_init();
343 }
344 
345 unsigned int plat_get_syscnt_freq2(void)
346 {
347 	unsigned int ver = zynqmp_get_silicon_ver();
348 
349 	switch (ver) {
350 	case ZYNQMP_CSU_VERSION_VELOCE:
351 		return 10000;
352 	case ZYNQMP_CSU_VERSION_EP108:
353 		return 4000000;
354 	case ZYNQMP_CSU_VERSION_QEMU:
355 		return 50000000;
356 	default:
357 		/* Do nothing in default case */
358 		break;
359 	}
360 
361 	return mmio_read_32(IOU_SCNTRS_BASEFREQ);
362 }
363