blob: ace4a0a95aa2e8905cdee5190581d6b9a0c3a38b [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
Soren Brinkmann76fcae32016-03-06 20:16:27 -08007#include <debug.h>
Soren Brinkmanne5bdcaa2016-06-22 09:02:56 -07008#include <generic_delay_timer.h>
Soren Brinkmann76fcae32016-03-06 20:16:27 -08009#include <mmio.h>
Soren Brinkmann76fcae32016-03-06 20:16:27 -080010#include <platform.h>
11#include <xlat_tables.h>
12#include "../zynqmp_private.h"
Siva Durga Prasad Paladugu00ae6c52017-02-20 17:55:50 +053013#include "pm_api_sys.h"
Soren Brinkmann76fcae32016-03-06 20:16:27 -080014
15/*
16 * Table of regions to map using the MMU.
17 * This doesn't include TZRAM as the 'mem_layout' argument passed to
18 * configure_mmu_elx() will give the available subset of that,
19 */
20const mmap_region_t plat_arm_mmap[] = {
21 { DEVICE0_BASE, DEVICE0_BASE, DEVICE0_SIZE, MT_DEVICE | MT_RW | MT_SECURE },
22 { DEVICE1_BASE, DEVICE1_BASE, DEVICE1_SIZE, MT_DEVICE | MT_RW | MT_SECURE },
23 { CRF_APB_BASE, CRF_APB_BASE, CRF_APB_SIZE, MT_DEVICE | MT_RW | MT_SECURE },
24 {0}
25};
26
27static unsigned int zynqmp_get_silicon_ver(void)
28{
Soren Brinkmann85863992016-09-16 10:34:47 -070029 static unsigned int ver;
Soren Brinkmann76fcae32016-03-06 20:16:27 -080030
Soren Brinkmann85863992016-09-16 10:34:47 -070031 if (!ver) {
32 ver = mmio_read_32(ZYNQMP_CSU_BASEADDR +
33 ZYNQMP_CSU_VERSION_OFFSET);
34 ver &= ZYNQMP_SILICON_VER_MASK;
35 ver >>= ZYNQMP_SILICON_VER_SHIFT;
36 }
Soren Brinkmann76fcae32016-03-06 20:16:27 -080037
38 return ver;
39}
40
41unsigned int zynqmp_get_uart_clk(void)
42{
43 unsigned int ver = zynqmp_get_silicon_ver();
44
45 switch (ver) {
46 case ZYNQMP_CSU_VERSION_VELOCE:
47 return 48000;
48 case ZYNQMP_CSU_VERSION_EP108:
49 return 25000000;
50 case ZYNQMP_CSU_VERSION_QEMU:
51 return 133000000;
Jonathan Wrightff957ed2018-03-14 15:24:00 +000052 default:
53 /* Do nothing in default case */
54 break;
Soren Brinkmann76fcae32016-03-06 20:16:27 -080055 }
56
57 return 100000000;
58}
59
Soren Brinkmann76fcae32016-03-06 20:16:27 -080060#if LOG_LEVEL >= LOG_LEVEL_NOTICE
61static const struct {
62 unsigned int id;
63 char *name;
64} zynqmp_devices[] = {
65 {
66 .id = 0x10,
67 .name = "3EG",
68 },
69 {
70 .id = 0x11,
71 .name = "2EG",
72 },
73 {
74 .id = 0x20,
75 .name = "5EV",
76 },
77 {
78 .id = 0x21,
79 .name = "4EV",
80 },
81 {
82 .id = 0x30,
83 .name = "7EV",
84 },
85 {
86 .id = 0x38,
87 .name = "9EG",
88 },
89 {
90 .id = 0x39,
91 .name = "6EG",
92 },
93 {
94 .id = 0x40,
95 .name = "11EG",
96 },
97 {
98 .id = 0x50,
99 .name = "15EG",
100 },
101 {
102 .id = 0x58,
103 .name = "19EG",
104 },
105 {
106 .id = 0x59,
107 .name = "17EG",
108 },
109};
110
Soren Brinkmanncb366812016-09-22 12:21:11 -0700111static unsigned int zynqmp_get_silicon_id(void)
112{
113 uint32_t id;
114
115 id = mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_IDCODE_OFFSET);
116
117 id &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK | ZYNQMP_CSU_IDCODE_SVD_MASK;
118 id >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT;
119
120 return id;
121}
122
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800123static char *zynqmp_get_silicon_idcode_name(void)
124{
125 unsigned int id;
126
127 id = zynqmp_get_silicon_id();
128 for (size_t i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
129 if (zynqmp_devices[i].id == id)
130 return zynqmp_devices[i].name;
131 }
132 return "UNKN";
133}
134
135static unsigned int zynqmp_get_rtl_ver(void)
136{
137 uint32_t ver;
138
139 ver = mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_VERSION_OFFSET);
140 ver &= ZYNQMP_RTL_VER_MASK;
141 ver >>= ZYNQMP_RTL_VER_SHIFT;
142
143 return ver;
144}
145
146static char *zynqmp_print_silicon_idcode(void)
147{
148 uint32_t id, maskid, tmp;
149
150 id = mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_IDCODE_OFFSET);
151
152 tmp = id;
153 tmp &= ZYNQMP_CSU_IDCODE_XILINX_ID_MASK |
Soren Brinkmann31114132016-05-20 07:05:00 -0700154 ZYNQMP_CSU_IDCODE_FAMILY_MASK;
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800155 maskid = ZYNQMP_CSU_IDCODE_XILINX_ID << ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT |
Soren Brinkmann31114132016-05-20 07:05:00 -0700156 ZYNQMP_CSU_IDCODE_FAMILY << ZYNQMP_CSU_IDCODE_FAMILY_SHIFT;
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800157 if (tmp != maskid) {
158 ERROR("Incorrect XILINX IDCODE 0x%x, maskid 0x%x\n", id, maskid);
159 return "UNKN";
160 }
161 VERBOSE("Xilinx IDCODE 0x%x\n", id);
162 return zynqmp_get_silicon_idcode_name();
163}
164
165static unsigned int zynqmp_get_ps_ver(void)
166{
167 uint32_t ver = mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_VERSION_OFFSET);
168
169 ver &= ZYNQMP_PS_VER_MASK;
170 ver >>= ZYNQMP_PS_VER_SHIFT;
171
172 return ver + 1;
173}
174
175static void zynqmp_print_platform_name(void)
176{
177 unsigned int ver = zynqmp_get_silicon_ver();
178 unsigned int rtl = zynqmp_get_rtl_ver();
179 char *label = "Unknown";
180
181 switch (ver) {
182 case ZYNQMP_CSU_VERSION_VELOCE:
183 label = "VELOCE";
184 break;
185 case ZYNQMP_CSU_VERSION_EP108:
186 label = "EP108";
187 break;
188 case ZYNQMP_CSU_VERSION_QEMU:
189 label = "QEMU";
190 break;
191 case ZYNQMP_CSU_VERSION_SILICON:
192 label = "silicon";
193 break;
Jonathan Wrightff957ed2018-03-14 15:24:00 +0000194 default:
195 /* Do nothing in default case */
196 break;
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800197 }
198
199 NOTICE("ATF running on XCZU%s/%s v%d/RTL%d.%d at 0x%x%s\n",
200 zynqmp_print_silicon_idcode(), label, zynqmp_get_ps_ver(),
201 (rtl & 0xf0) >> 4, rtl & 0xf, BL31_BASE,
202 zynqmp_is_pmu_up() ? ", with PMU firmware" : "");
203}
204#else
205static inline void zynqmp_print_platform_name(void) { }
206#endif
207
208/*
209 * Indicator for PMUFW discovery:
210 * 0 = No FW found
211 * non-zero = FW is present
212 */
213static int zynqmp_pmufw_present;
214
215/*
216 * zynqmp_discover_pmufw - Discover presence of PMUFW
217 *
218 * Discover the presence of PMUFW and store it for later run-time queries
219 * through zynqmp_is_pmu_up.
220 * NOTE: This discovery method is fragile and will break if:
221 * - setting FW_PRESENT is done by PMUFW itself and could be left out in PMUFW
222 * (be it by error or intentionally)
223 * - XPPU/XMPU may restrict ATF's access to the PMU address space
224 */
225static int zynqmp_discover_pmufw(void)
226{
227 zynqmp_pmufw_present = mmio_read_32(PMU_GLOBAL_CNTRL);
228 zynqmp_pmufw_present &= PMU_GLOBAL_CNTRL_FW_IS_PRESENT;
229
230 return !!zynqmp_pmufw_present;
231}
232
233/*
234 * zynqmp_is_pmu_up - Find if PMU firmware is up and running
235 *
236 * Return 0 if firmware is not available, non 0 otherwise
237 */
238int zynqmp_is_pmu_up(void)
239{
240 return zynqmp_pmufw_present;
241}
242
Soren Brinkmannb43d9432016-04-18 11:49:42 -0700243unsigned int zynqmp_get_bootmode(void)
244{
Siva Durga Prasad Paladugu00ae6c52017-02-20 17:55:50 +0530245 uint32_t r;
246
247 if (zynqmp_is_pmu_up())
248 pm_mmio_read(CRL_APB_BOOT_MODE_USER, &r);
249 else
250 r = mmio_read_32(CRL_APB_BOOT_MODE_USER);
Soren Brinkmannb43d9432016-04-18 11:49:42 -0700251
252 return r & CRL_APB_BOOT_MODE_MASK;
253}
254
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800255void zynqmp_config_setup(void)
256{
257 zynqmp_discover_pmufw();
258 zynqmp_print_platform_name();
Soren Brinkmanne5bdcaa2016-06-22 09:02:56 -0700259 generic_delay_timer_init();
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800260}
261
Antonio Nino Diaze82e29c2016-05-19 10:00:28 +0100262unsigned int plat_get_syscnt_freq2(void)
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800263{
Soren Brinkmanncfcb1a22016-09-16 10:31:06 -0700264 unsigned int ver = zynqmp_get_silicon_ver();
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800265
Soren Brinkmanncfcb1a22016-09-16 10:31:06 -0700266 switch (ver) {
267 case ZYNQMP_CSU_VERSION_VELOCE:
268 return 10000;
269 case ZYNQMP_CSU_VERSION_EP108:
270 return 4000000;
271 case ZYNQMP_CSU_VERSION_QEMU:
272 return 50000000;
Jonathan Wrightff957ed2018-03-14 15:24:00 +0000273 default:
274 /* Do nothing in default case */
275 break;
Soren Brinkmanncfcb1a22016-09-16 10:31:06 -0700276 }
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800277
Soren Brinkmanncfcb1a22016-09-16 10:31:06 -0700278 return mmio_read_32(IOU_SCNTRS_BASEFREQ);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800279}