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