blob: 8ff6c436046ff86160127576ff78aadc0b21e3af [file] [log] [blame]
Soren Brinkmann76fcae32016-03-06 20:16:27 -08001/*
2 * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
3 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Soren Brinkmann76fcae32016-03-06 20:16:27 -08005 */
6
Siva Durga Prasad Paladugub76656d2018-03-05 18:47:15 +05307#include <stdbool.h>
8#include <string.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00009
10#include <common/debug.h>
11#include <drivers/generic_delay_timer.h>
12#include <lib/mmio.h>
13#include <lib/xlat_tables/xlat_tables.h>
Jolly Shah0bfd7002019-01-08 11:10:47 -080014#include <plat_private.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000015#include <plat/common/platform.h>
16
Siva Durga Prasad Paladugu00ae6c52017-02-20 17:55:50 +053017#include "pm_api_sys.h"
Soren Brinkmann76fcae32016-03-06 20:16:27 -080018
19/*
20 * Table of regions to map using the MMU.
21 * This doesn't include TZRAM as the 'mem_layout' argument passed to
22 * configure_mmu_elx() will give the available subset of that,
23 */
24const mmap_region_t plat_arm_mmap[] = {
25 { DEVICE0_BASE, DEVICE0_BASE, DEVICE0_SIZE, MT_DEVICE | MT_RW | MT_SECURE },
26 { DEVICE1_BASE, DEVICE1_BASE, DEVICE1_SIZE, MT_DEVICE | MT_RW | MT_SECURE },
27 { CRF_APB_BASE, CRF_APB_BASE, CRF_APB_SIZE, MT_DEVICE | MT_RW | MT_SECURE },
28 {0}
29};
30
31static unsigned int zynqmp_get_silicon_ver(void)
32{
Soren Brinkmann85863992016-09-16 10:34:47 -070033 static unsigned int ver;
Soren Brinkmann76fcae32016-03-06 20:16:27 -080034
Soren Brinkmann85863992016-09-16 10:34:47 -070035 if (!ver) {
36 ver = mmio_read_32(ZYNQMP_CSU_BASEADDR +
37 ZYNQMP_CSU_VERSION_OFFSET);
38 ver &= ZYNQMP_SILICON_VER_MASK;
39 ver >>= ZYNQMP_SILICON_VER_SHIFT;
40 }
Soren Brinkmann76fcae32016-03-06 20:16:27 -080041
42 return ver;
43}
44
45unsigned int zynqmp_get_uart_clk(void)
46{
47 unsigned int ver = zynqmp_get_silicon_ver();
48
Siva Durga Prasad Paladugudff07122018-09-04 18:02:25 +053049 if (ver == ZYNQMP_CSU_VERSION_QEMU)
Soren Brinkmann76fcae32016-03-06 20:16:27 -080050 return 133000000;
Siva Durga Prasad Paladugudff07122018-09-04 18:02:25 +053051 else
52 return 100000000;
Soren Brinkmann76fcae32016-03-06 20:16:27 -080053}
54
Soren Brinkmann76fcae32016-03-06 20:16:27 -080055#if LOG_LEVEL >= LOG_LEVEL_NOTICE
56static const struct {
57 unsigned int id;
Siva Durga Prasad Paladugu83e37252018-05-01 11:10:25 +053058 unsigned int ver;
Soren Brinkmann76fcae32016-03-06 20:16:27 -080059 char *name;
Siva Durga Prasad Paladugub76656d2018-03-05 18:47:15 +053060 bool evexists;
Soren Brinkmann76fcae32016-03-06 20:16:27 -080061} zynqmp_devices[] = {
62 {
63 .id = 0x10,
64 .name = "3EG",
65 },
66 {
Siva Durga Prasad Paladugu83e37252018-05-01 11:10:25 +053067 .id = 0x10,
68 .ver = 0x2c,
69 .name = "3CG",
70 },
71 {
Soren Brinkmann76fcae32016-03-06 20:16:27 -080072 .id = 0x11,
73 .name = "2EG",
74 },
75 {
Siva Durga Prasad Paladugu83e37252018-05-01 11:10:25 +053076 .id = 0x11,
77 .ver = 0x2c,
78 .name = "2CG",
79 },
80 {
Soren Brinkmann76fcae32016-03-06 20:16:27 -080081 .id = 0x20,
82 .name = "5EV",
Siva Durga Prasad Paladugub76656d2018-03-05 18:47:15 +053083 .evexists = true,
Soren Brinkmann76fcae32016-03-06 20:16:27 -080084 },
85 {
Siva Durga Prasad Paladugu83e37252018-05-01 11:10:25 +053086 .id = 0x20,
87 .ver = 0x100,
88 .name = "5EG",
Siva Durga Prasad Paladugub76656d2018-03-05 18:47:15 +053089 .evexists = true,
Siva Durga Prasad Paladugu83e37252018-05-01 11:10:25 +053090 },
91 {
92 .id = 0x20,
93 .ver = 0x12c,
94 .name = "5CG",
95 },
96 {
Soren Brinkmann76fcae32016-03-06 20:16:27 -080097 .id = 0x21,
98 .name = "4EV",
Siva Durga Prasad Paladugub76656d2018-03-05 18:47:15 +053099 .evexists = true,
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800100 },
101 {
Siva Durga Prasad Paladugu83e37252018-05-01 11:10:25 +0530102 .id = 0x21,
103 .ver = 0x100,
104 .name = "4EG",
Siva Durga Prasad Paladugub76656d2018-03-05 18:47:15 +0530105 .evexists = true,
Siva Durga Prasad Paladugu83e37252018-05-01 11:10:25 +0530106 },
107 {
108 .id = 0x21,
109 .ver = 0x12c,
110 .name = "4CG",
111 },
112 {
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800113 .id = 0x30,
114 .name = "7EV",
Siva Durga Prasad Paladugub76656d2018-03-05 18:47:15 +0530115 .evexists = true,
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800116 },
117 {
Siva Durga Prasad Paladugu83e37252018-05-01 11:10:25 +0530118 .id = 0x30,
119 .ver = 0x100,
120 .name = "7EG",
Siva Durga Prasad Paladugub76656d2018-03-05 18:47:15 +0530121 .evexists = true,
Siva Durga Prasad Paladugu83e37252018-05-01 11:10:25 +0530122 },
123 {
124 .id = 0x30,
125 .ver = 0x12c,
126 .name = "7CG",
127 },
128 {
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800129 .id = 0x38,
130 .name = "9EG",
131 },
132 {
Siva Durga Prasad Paladugu83e37252018-05-01 11:10:25 +0530133 .id = 0x38,
134 .ver = 0x2c,
135 .name = "9CG",
136 },
137 {
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800138 .id = 0x39,
139 .name = "6EG",
140 },
141 {
Siva Durga Prasad Paladugu83e37252018-05-01 11:10:25 +0530142 .id = 0x39,
143 .ver = 0x2c,
144 .name = "6CG",
145 },
146 {
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800147 .id = 0x40,
148 .name = "11EG",
149 },
Siva Durga Prasad Paladugu83e37252018-05-01 11:10:25 +0530150 { /* For testing purpose only */
151 .id = 0x50,
152 .ver = 0x2c,
153 .name = "15CG",
154 },
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800155 {
156 .id = 0x50,
157 .name = "15EG",
158 },
159 {
160 .id = 0x58,
161 .name = "19EG",
162 },
163 {
164 .id = 0x59,
165 .name = "17EG",
166 },
Siva Durga Prasad Paladugu19d69c02017-06-06 12:54:52 +0530167 {
168 .id = 0x60,
169 .name = "28DR",
170 },
171 {
172 .id = 0x61,
173 .name = "21DR",
174 },
175 {
176 .id = 0x62,
177 .name = "29DR",
178 },
179 {
180 .id = 0x63,
181 .name = "23DR",
182 },
183 {
184 .id = 0x64,
185 .name = "27DR",
186 },
187 {
188 .id = 0x65,
189 .name = "25DR",
190 },
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800191};
192
Siva Durga Prasad Paladugub76656d2018-03-05 18:47:15 +0530193#define ZYNQMP_PL_STATUS_BIT 9
194#define ZYNQMP_PL_STATUS_MASK BIT(ZYNQMP_PL_STATUS_BIT)
195#define ZYNQMP_CSU_VERSION_MASK ~(ZYNQMP_PL_STATUS_MASK)
196
197static char *zynqmp_get_silicon_idcode_name(void)
Soren Brinkmanncb366812016-09-22 12:21:11 -0700198{
Siva Durga Prasad Paladugub76656d2018-03-05 18:47:15 +0530199 uint32_t id, ver, chipid[2];
200 size_t i, j, len;
Siva Durga Prasad Paladugub76656d2018-03-05 18:47:15 +0530201 const char *name = "EG/EV";
Soren Brinkmanncb366812016-09-22 12:21:11 -0700202
Siva Durga Prasad Paladugu6a8933c2018-06-20 17:03:57 +0530203#ifdef IMAGE_BL32
204 /*
205 * For BL32, get the chip id info directly by reading corresponding
206 * registers instead of making pm call. This has limitation
207 * that these registers should be configured to have access
208 * from APU which is default case.
209 */
210 chipid[0] = mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_IDCODE_OFFSET);
211 chipid[1] = mmio_read_32(EFUSE_BASEADDR + EFUSE_IPDISABLE_OFFSET);
212#else
213 if (pm_get_chipid(chipid) != PM_RET_SUCCESS)
Siva Durga Prasad Paladugub76656d2018-03-05 18:47:15 +0530214 return "UNKN";
Siva Durga Prasad Paladugu6a8933c2018-06-20 17:03:57 +0530215#endif
Soren Brinkmanncb366812016-09-22 12:21:11 -0700216
Siva Durga Prasad Paladugub76656d2018-03-05 18:47:15 +0530217 id = chipid[0] & (ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK |
218 ZYNQMP_CSU_IDCODE_SVD_MASK);
Soren Brinkmanncb366812016-09-22 12:21:11 -0700219 id >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT;
Siva Durga Prasad Paladugub76656d2018-03-05 18:47:15 +0530220 ver = chipid[1] >> ZYNQMP_EFUSE_IPDISABLE_SHIFT;
Soren Brinkmanncb366812016-09-22 12:21:11 -0700221
Siva Durga Prasad Paladugub76656d2018-03-05 18:47:15 +0530222 for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
223 if (zynqmp_devices[i].id == id &&
224 zynqmp_devices[i].ver == (ver & ZYNQMP_CSU_VERSION_MASK))
225 break;
226 }
Siva Durga Prasad Paladugu83e37252018-05-01 11:10:25 +0530227
Siva Durga Prasad Paladugub76656d2018-03-05 18:47:15 +0530228 if (i >= ARRAY_SIZE(zynqmp_devices))
229 return "UNKN";
Siva Durga Prasad Paladugu83e37252018-05-01 11:10:25 +0530230
Siva Durga Prasad Paladugub76656d2018-03-05 18:47:15 +0530231 if (!zynqmp_devices[i].evexists)
232 return zynqmp_devices[i].name;
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800233
Siva Durga Prasad Paladugub76656d2018-03-05 18:47:15 +0530234 if (ver & ZYNQMP_PL_STATUS_MASK)
235 return zynqmp_devices[i].name;
Siva Durga Prasad Paladugu83e37252018-05-01 11:10:25 +0530236
Siva Durga Prasad Paladugub76656d2018-03-05 18:47:15 +0530237 len = strlen(zynqmp_devices[i].name) - 2;
238 for (j = 0; j < strlen(name); j++) {
239 zynqmp_devices[i].name[len] = name[j];
240 len++;
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800241 }
Siva Durga Prasad Paladugub76656d2018-03-05 18:47:15 +0530242 zynqmp_devices[i].name[len] = '\0';
243
244 return zynqmp_devices[i].name;
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800245}
246
247static unsigned int zynqmp_get_rtl_ver(void)
248{
249 uint32_t ver;
250
251 ver = mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_VERSION_OFFSET);
252 ver &= ZYNQMP_RTL_VER_MASK;
253 ver >>= ZYNQMP_RTL_VER_SHIFT;
254
255 return ver;
256}
257
258static char *zynqmp_print_silicon_idcode(void)
259{
260 uint32_t id, maskid, tmp;
261
262 id = mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_IDCODE_OFFSET);
263
264 tmp = id;
265 tmp &= ZYNQMP_CSU_IDCODE_XILINX_ID_MASK |
Soren Brinkmann31114132016-05-20 07:05:00 -0700266 ZYNQMP_CSU_IDCODE_FAMILY_MASK;
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800267 maskid = ZYNQMP_CSU_IDCODE_XILINX_ID << ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT |
Soren Brinkmann31114132016-05-20 07:05:00 -0700268 ZYNQMP_CSU_IDCODE_FAMILY << ZYNQMP_CSU_IDCODE_FAMILY_SHIFT;
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800269 if (tmp != maskid) {
270 ERROR("Incorrect XILINX IDCODE 0x%x, maskid 0x%x\n", id, maskid);
271 return "UNKN";
272 }
273 VERBOSE("Xilinx IDCODE 0x%x\n", id);
274 return zynqmp_get_silicon_idcode_name();
275}
276
277static unsigned int zynqmp_get_ps_ver(void)
278{
279 uint32_t ver = mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_VERSION_OFFSET);
280
281 ver &= ZYNQMP_PS_VER_MASK;
282 ver >>= ZYNQMP_PS_VER_SHIFT;
283
284 return ver + 1;
285}
286
287static void zynqmp_print_platform_name(void)
288{
289 unsigned int ver = zynqmp_get_silicon_ver();
290 unsigned int rtl = zynqmp_get_rtl_ver();
291 char *label = "Unknown";
292
293 switch (ver) {
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800294 case ZYNQMP_CSU_VERSION_QEMU:
295 label = "QEMU";
296 break;
297 case ZYNQMP_CSU_VERSION_SILICON:
298 label = "silicon";
299 break;
Jonathan Wrightff957ed2018-03-14 15:24:00 +0000300 default:
301 /* Do nothing in default case */
302 break;
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800303 }
304
Siva Durga Prasad Paladugu40808bc2018-04-30 19:43:03 +0530305 NOTICE("ATF running on XCZU%s/%s v%d/RTL%d.%d at 0x%x\n",
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800306 zynqmp_print_silicon_idcode(), label, zynqmp_get_ps_ver(),
Siva Durga Prasad Paladugu40808bc2018-04-30 19:43:03 +0530307 (rtl & 0xf0) >> 4, rtl & 0xf, BL31_BASE);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800308}
309#else
310static inline void zynqmp_print_platform_name(void) { }
311#endif
312
Soren Brinkmannb43d9432016-04-18 11:49:42 -0700313unsigned int zynqmp_get_bootmode(void)
314{
Siva Durga Prasad Paladugu00ae6c52017-02-20 17:55:50 +0530315 uint32_t r;
Siva Durga Prasad Paladugu40808bc2018-04-30 19:43:03 +0530316 unsigned int ret;
Siva Durga Prasad Paladugu00ae6c52017-02-20 17:55:50 +0530317
Siva Durga Prasad Paladugu40808bc2018-04-30 19:43:03 +0530318 ret = pm_mmio_read(CRL_APB_BOOT_MODE_USER, &r);
319
320 if (ret != PM_RET_SUCCESS)
Siva Durga Prasad Paladugu00ae6c52017-02-20 17:55:50 +0530321 r = mmio_read_32(CRL_APB_BOOT_MODE_USER);
Soren Brinkmannb43d9432016-04-18 11:49:42 -0700322
323 return r & CRL_APB_BOOT_MODE_MASK;
324}
325
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800326void zynqmp_config_setup(void)
327{
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800328 zynqmp_print_platform_name();
Soren Brinkmanne5bdcaa2016-06-22 09:02:56 -0700329 generic_delay_timer_init();
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800330}
331
Antonio Nino Diaze82e29c2016-05-19 10:00:28 +0100332unsigned int plat_get_syscnt_freq2(void)
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800333{
Soren Brinkmanncfcb1a22016-09-16 10:31:06 -0700334 unsigned int ver = zynqmp_get_silicon_ver();
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800335
Siva Durga Prasad Paladugudff07122018-09-04 18:02:25 +0530336 if (ver == ZYNQMP_CSU_VERSION_QEMU)
Soren Brinkmanncfcb1a22016-09-16 10:31:06 -0700337 return 50000000;
Siva Durga Prasad Paladugudff07122018-09-04 18:02:25 +0530338 else
339 return mmio_read_32(IOU_SCNTRS_BASEFREQ);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800340}