1c8284409SSoren Brinkmann /* 2c8284409SSoren Brinkmann * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. 3c8284409SSoren Brinkmann * 482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause 5c8284409SSoren Brinkmann */ 6c8284409SSoren Brinkmann 7c8284409SSoren Brinkmann #include <debug.h> 8e1cb4da4SSoren Brinkmann #include <generic_delay_timer.h> 9c8284409SSoren Brinkmann #include <mmio.h> 10c8284409SSoren Brinkmann #include <platform.h> 11c8284409SSoren Brinkmann #include <xlat_tables.h> 12c8284409SSoren Brinkmann #include "../zynqmp_private.h" 1329bd0e66SSiva Durga Prasad Paladugu #include "pm_api_sys.h" 14c8284409SSoren Brinkmann 15c8284409SSoren Brinkmann /* 16c8284409SSoren Brinkmann * Table of regions to map using the MMU. 17c8284409SSoren Brinkmann * This doesn't include TZRAM as the 'mem_layout' argument passed to 18c8284409SSoren Brinkmann * configure_mmu_elx() will give the available subset of that, 19c8284409SSoren Brinkmann */ 20c8284409SSoren Brinkmann const mmap_region_t plat_arm_mmap[] = { 21c8284409SSoren Brinkmann { DEVICE0_BASE, DEVICE0_BASE, DEVICE0_SIZE, MT_DEVICE | MT_RW | MT_SECURE }, 22c8284409SSoren Brinkmann { DEVICE1_BASE, DEVICE1_BASE, DEVICE1_SIZE, MT_DEVICE | MT_RW | MT_SECURE }, 23c8284409SSoren Brinkmann { CRF_APB_BASE, CRF_APB_BASE, CRF_APB_SIZE, MT_DEVICE | MT_RW | MT_SECURE }, 24c8284409SSoren Brinkmann {0} 25c8284409SSoren Brinkmann }; 26c8284409SSoren Brinkmann 27c8284409SSoren Brinkmann static unsigned int zynqmp_get_silicon_ver(void) 28c8284409SSoren Brinkmann { 29466675c2SSoren Brinkmann static unsigned int ver; 30c8284409SSoren Brinkmann 31466675c2SSoren Brinkmann if (!ver) { 32466675c2SSoren Brinkmann ver = mmio_read_32(ZYNQMP_CSU_BASEADDR + 33466675c2SSoren Brinkmann ZYNQMP_CSU_VERSION_OFFSET); 34c8284409SSoren Brinkmann ver &= ZYNQMP_SILICON_VER_MASK; 35c8284409SSoren Brinkmann ver >>= ZYNQMP_SILICON_VER_SHIFT; 36466675c2SSoren Brinkmann } 37c8284409SSoren Brinkmann 38c8284409SSoren Brinkmann return ver; 39c8284409SSoren Brinkmann } 40c8284409SSoren Brinkmann 41c8284409SSoren Brinkmann unsigned int zynqmp_get_uart_clk(void) 42c8284409SSoren Brinkmann { 43c8284409SSoren Brinkmann unsigned int ver = zynqmp_get_silicon_ver(); 44c8284409SSoren Brinkmann 45c8284409SSoren Brinkmann switch (ver) { 46c8284409SSoren Brinkmann case ZYNQMP_CSU_VERSION_VELOCE: 47c8284409SSoren Brinkmann return 48000; 48c8284409SSoren Brinkmann case ZYNQMP_CSU_VERSION_EP108: 49c8284409SSoren Brinkmann return 25000000; 50c8284409SSoren Brinkmann case ZYNQMP_CSU_VERSION_QEMU: 51c8284409SSoren Brinkmann return 133000000; 52649c48f5SJonathan Wright default: 53649c48f5SJonathan Wright /* Do nothing in default case */ 54649c48f5SJonathan Wright break; 55c8284409SSoren Brinkmann } 56c8284409SSoren Brinkmann 57c8284409SSoren Brinkmann return 100000000; 58c8284409SSoren Brinkmann } 59c8284409SSoren Brinkmann 60c8284409SSoren Brinkmann #if LOG_LEVEL >= LOG_LEVEL_NOTICE 61c8284409SSoren Brinkmann static const struct { 62c8284409SSoren Brinkmann unsigned int id; 63915d4872SSiva Durga Prasad Paladugu unsigned int ver; 64c8284409SSoren Brinkmann char *name; 65c8284409SSoren Brinkmann } zynqmp_devices[] = { 66c8284409SSoren Brinkmann { 67c8284409SSoren Brinkmann .id = 0x10, 68c8284409SSoren Brinkmann .name = "3EG", 69c8284409SSoren Brinkmann }, 70c8284409SSoren Brinkmann { 71915d4872SSiva Durga Prasad Paladugu .id = 0x10, 72915d4872SSiva Durga Prasad Paladugu .ver = 0x2c, 73915d4872SSiva Durga Prasad Paladugu .name = "3CG", 74915d4872SSiva Durga Prasad Paladugu }, 75915d4872SSiva Durga Prasad Paladugu { 76c8284409SSoren Brinkmann .id = 0x11, 77c8284409SSoren Brinkmann .name = "2EG", 78c8284409SSoren Brinkmann }, 79c8284409SSoren Brinkmann { 80915d4872SSiva Durga Prasad Paladugu .id = 0x11, 81915d4872SSiva Durga Prasad Paladugu .ver = 0x2c, 82915d4872SSiva Durga Prasad Paladugu .name = "2CG", 83915d4872SSiva Durga Prasad Paladugu }, 84915d4872SSiva Durga Prasad Paladugu { 85c8284409SSoren Brinkmann .id = 0x20, 86c8284409SSoren Brinkmann .name = "5EV", 87c8284409SSoren Brinkmann }, 88c8284409SSoren Brinkmann { 89915d4872SSiva Durga Prasad Paladugu .id = 0x20, 90915d4872SSiva Durga Prasad Paladugu .ver = 0x100, 91915d4872SSiva Durga Prasad Paladugu .name = "5EG", 92915d4872SSiva Durga Prasad Paladugu }, 93915d4872SSiva Durga Prasad Paladugu { 94915d4872SSiva Durga Prasad Paladugu .id = 0x20, 95915d4872SSiva Durga Prasad Paladugu .ver = 0x12c, 96915d4872SSiva Durga Prasad Paladugu .name = "5CG", 97915d4872SSiva Durga Prasad Paladugu }, 98915d4872SSiva Durga Prasad Paladugu { 99c8284409SSoren Brinkmann .id = 0x21, 100c8284409SSoren Brinkmann .name = "4EV", 101c8284409SSoren Brinkmann }, 102c8284409SSoren Brinkmann { 103915d4872SSiva Durga Prasad Paladugu .id = 0x21, 104915d4872SSiva Durga Prasad Paladugu .ver = 0x100, 105915d4872SSiva Durga Prasad Paladugu .name = "4EG", 106915d4872SSiva Durga Prasad Paladugu }, 107915d4872SSiva Durga Prasad Paladugu { 108915d4872SSiva Durga Prasad Paladugu .id = 0x21, 109915d4872SSiva Durga Prasad Paladugu .ver = 0x12c, 110915d4872SSiva Durga Prasad Paladugu .name = "4CG", 111915d4872SSiva Durga Prasad Paladugu }, 112915d4872SSiva Durga Prasad Paladugu { 113c8284409SSoren Brinkmann .id = 0x30, 114c8284409SSoren Brinkmann .name = "7EV", 115c8284409SSoren Brinkmann }, 116c8284409SSoren Brinkmann { 117915d4872SSiva Durga Prasad Paladugu .id = 0x30, 118915d4872SSiva Durga Prasad Paladugu .ver = 0x100, 119915d4872SSiva Durga Prasad Paladugu .name = "7EG", 120915d4872SSiva Durga Prasad Paladugu }, 121915d4872SSiva Durga Prasad Paladugu { 122915d4872SSiva Durga Prasad Paladugu .id = 0x30, 123915d4872SSiva Durga Prasad Paladugu .ver = 0x12c, 124915d4872SSiva Durga Prasad Paladugu .name = "7CG", 125915d4872SSiva Durga Prasad Paladugu }, 126915d4872SSiva Durga Prasad Paladugu { 127c8284409SSoren Brinkmann .id = 0x38, 128c8284409SSoren Brinkmann .name = "9EG", 129c8284409SSoren Brinkmann }, 130c8284409SSoren Brinkmann { 131915d4872SSiva Durga Prasad Paladugu .id = 0x38, 132915d4872SSiva Durga Prasad Paladugu .ver = 0x2c, 133915d4872SSiva Durga Prasad Paladugu .name = "9CG", 134915d4872SSiva Durga Prasad Paladugu }, 135915d4872SSiva Durga Prasad Paladugu { 136c8284409SSoren Brinkmann .id = 0x39, 137c8284409SSoren Brinkmann .name = "6EG", 138c8284409SSoren Brinkmann }, 139c8284409SSoren Brinkmann { 140915d4872SSiva Durga Prasad Paladugu .id = 0x39, 141915d4872SSiva Durga Prasad Paladugu .ver = 0x2c, 142915d4872SSiva Durga Prasad Paladugu .name = "6CG", 143915d4872SSiva Durga Prasad Paladugu }, 144915d4872SSiva Durga Prasad Paladugu { 145c8284409SSoren Brinkmann .id = 0x40, 146c8284409SSoren Brinkmann .name = "11EG", 147c8284409SSoren Brinkmann }, 148915d4872SSiva Durga Prasad Paladugu { /* For testing purpose only */ 149915d4872SSiva Durga Prasad Paladugu .id = 0x50, 150915d4872SSiva Durga Prasad Paladugu .ver = 0x2c, 151915d4872SSiva Durga Prasad Paladugu .name = "15CG", 152915d4872SSiva Durga Prasad Paladugu }, 153c8284409SSoren Brinkmann { 154c8284409SSoren Brinkmann .id = 0x50, 155c8284409SSoren Brinkmann .name = "15EG", 156c8284409SSoren Brinkmann }, 157c8284409SSoren Brinkmann { 158c8284409SSoren Brinkmann .id = 0x58, 159c8284409SSoren Brinkmann .name = "19EG", 160c8284409SSoren Brinkmann }, 161c8284409SSoren Brinkmann { 162c8284409SSoren Brinkmann .id = 0x59, 163c8284409SSoren Brinkmann .name = "17EG", 164c8284409SSoren Brinkmann }, 165d9710aebSSiva Durga Prasad Paladugu { 166d9710aebSSiva Durga Prasad Paladugu .id = 0x60, 167d9710aebSSiva Durga Prasad Paladugu .name = "28DR", 168d9710aebSSiva Durga Prasad Paladugu }, 169d9710aebSSiva Durga Prasad Paladugu { 170d9710aebSSiva Durga Prasad Paladugu .id = 0x61, 171d9710aebSSiva Durga Prasad Paladugu .name = "21DR", 172d9710aebSSiva Durga Prasad Paladugu }, 173d9710aebSSiva Durga Prasad Paladugu { 174d9710aebSSiva Durga Prasad Paladugu .id = 0x62, 175d9710aebSSiva Durga Prasad Paladugu .name = "29DR", 176d9710aebSSiva Durga Prasad Paladugu }, 177d9710aebSSiva Durga Prasad Paladugu { 178d9710aebSSiva Durga Prasad Paladugu .id = 0x63, 179d9710aebSSiva Durga Prasad Paladugu .name = "23DR", 180d9710aebSSiva Durga Prasad Paladugu }, 181d9710aebSSiva Durga Prasad Paladugu { 182d9710aebSSiva Durga Prasad Paladugu .id = 0x64, 183d9710aebSSiva Durga Prasad Paladugu .name = "27DR", 184d9710aebSSiva Durga Prasad Paladugu }, 185d9710aebSSiva Durga Prasad Paladugu { 186d9710aebSSiva Durga Prasad Paladugu .id = 0x65, 187d9710aebSSiva Durga Prasad Paladugu .name = "25DR", 188d9710aebSSiva Durga Prasad Paladugu }, 189c8284409SSoren Brinkmann }; 190c8284409SSoren Brinkmann 19146cb684fSSoren Brinkmann static unsigned int zynqmp_get_silicon_id(void) 19246cb684fSSoren Brinkmann { 19346cb684fSSoren Brinkmann uint32_t id; 19446cb684fSSoren Brinkmann 19546cb684fSSoren Brinkmann id = mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_IDCODE_OFFSET); 19646cb684fSSoren Brinkmann 19746cb684fSSoren Brinkmann id &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK | ZYNQMP_CSU_IDCODE_SVD_MASK; 19846cb684fSSoren Brinkmann id >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT; 19946cb684fSSoren Brinkmann 20046cb684fSSoren Brinkmann return id; 20146cb684fSSoren Brinkmann } 20246cb684fSSoren Brinkmann 203915d4872SSiva Durga Prasad Paladugu static unsigned int zynqmp_get_silicon_id2(void) 204915d4872SSiva Durga Prasad Paladugu { 205915d4872SSiva Durga Prasad Paladugu uint32_t id; 206915d4872SSiva Durga Prasad Paladugu 207915d4872SSiva Durga Prasad Paladugu id = mmio_read_32(EFUSE_BASEADDR + EFUSE_IPDISABLE_OFFSET); 208915d4872SSiva Durga Prasad Paladugu id &= EFUSE_IPDISABLE_VERSION; 209915d4872SSiva Durga Prasad Paladugu 210915d4872SSiva Durga Prasad Paladugu return id; 211915d4872SSiva Durga Prasad Paladugu } 212915d4872SSiva Durga Prasad Paladugu 213c8284409SSoren Brinkmann static char *zynqmp_get_silicon_idcode_name(void) 214c8284409SSoren Brinkmann { 215915d4872SSiva Durga Prasad Paladugu unsigned int id, ver; 216915d4872SSiva Durga Prasad Paladugu size_t i; 217c8284409SSoren Brinkmann 218c8284409SSoren Brinkmann id = zynqmp_get_silicon_id(); 219915d4872SSiva Durga Prasad Paladugu ver = zynqmp_get_silicon_id2(); 220915d4872SSiva Durga Prasad Paladugu 221915d4872SSiva Durga Prasad Paladugu for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) { 222915d4872SSiva Durga Prasad Paladugu if (zynqmp_devices[i].id == id && zynqmp_devices[i].ver == ver) 223c8284409SSoren Brinkmann return zynqmp_devices[i].name; 224c8284409SSoren Brinkmann } 225c8284409SSoren Brinkmann return "UNKN"; 226c8284409SSoren Brinkmann } 227c8284409SSoren Brinkmann 228c8284409SSoren Brinkmann static unsigned int zynqmp_get_rtl_ver(void) 229c8284409SSoren Brinkmann { 230c8284409SSoren Brinkmann uint32_t ver; 231c8284409SSoren Brinkmann 232c8284409SSoren Brinkmann ver = mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_VERSION_OFFSET); 233c8284409SSoren Brinkmann ver &= ZYNQMP_RTL_VER_MASK; 234c8284409SSoren Brinkmann ver >>= ZYNQMP_RTL_VER_SHIFT; 235c8284409SSoren Brinkmann 236c8284409SSoren Brinkmann return ver; 237c8284409SSoren Brinkmann } 238c8284409SSoren Brinkmann 239c8284409SSoren Brinkmann static char *zynqmp_print_silicon_idcode(void) 240c8284409SSoren Brinkmann { 241c8284409SSoren Brinkmann uint32_t id, maskid, tmp; 242c8284409SSoren Brinkmann 243c8284409SSoren Brinkmann id = mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_IDCODE_OFFSET); 244c8284409SSoren Brinkmann 245c8284409SSoren Brinkmann tmp = id; 246c8284409SSoren Brinkmann tmp &= ZYNQMP_CSU_IDCODE_XILINX_ID_MASK | 247648fe99eSSoren Brinkmann ZYNQMP_CSU_IDCODE_FAMILY_MASK; 248c8284409SSoren Brinkmann maskid = ZYNQMP_CSU_IDCODE_XILINX_ID << ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT | 249648fe99eSSoren Brinkmann ZYNQMP_CSU_IDCODE_FAMILY << ZYNQMP_CSU_IDCODE_FAMILY_SHIFT; 250c8284409SSoren Brinkmann if (tmp != maskid) { 251c8284409SSoren Brinkmann ERROR("Incorrect XILINX IDCODE 0x%x, maskid 0x%x\n", id, maskid); 252c8284409SSoren Brinkmann return "UNKN"; 253c8284409SSoren Brinkmann } 254c8284409SSoren Brinkmann VERBOSE("Xilinx IDCODE 0x%x\n", id); 255c8284409SSoren Brinkmann return zynqmp_get_silicon_idcode_name(); 256c8284409SSoren Brinkmann } 257c8284409SSoren Brinkmann 258c8284409SSoren Brinkmann static unsigned int zynqmp_get_ps_ver(void) 259c8284409SSoren Brinkmann { 260c8284409SSoren Brinkmann uint32_t ver = mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_VERSION_OFFSET); 261c8284409SSoren Brinkmann 262c8284409SSoren Brinkmann ver &= ZYNQMP_PS_VER_MASK; 263c8284409SSoren Brinkmann ver >>= ZYNQMP_PS_VER_SHIFT; 264c8284409SSoren Brinkmann 265c8284409SSoren Brinkmann return ver + 1; 266c8284409SSoren Brinkmann } 267c8284409SSoren Brinkmann 268c8284409SSoren Brinkmann static void zynqmp_print_platform_name(void) 269c8284409SSoren Brinkmann { 270c8284409SSoren Brinkmann unsigned int ver = zynqmp_get_silicon_ver(); 271c8284409SSoren Brinkmann unsigned int rtl = zynqmp_get_rtl_ver(); 272c8284409SSoren Brinkmann char *label = "Unknown"; 273c8284409SSoren Brinkmann 274c8284409SSoren Brinkmann switch (ver) { 275c8284409SSoren Brinkmann case ZYNQMP_CSU_VERSION_VELOCE: 276c8284409SSoren Brinkmann label = "VELOCE"; 277c8284409SSoren Brinkmann break; 278c8284409SSoren Brinkmann case ZYNQMP_CSU_VERSION_EP108: 279c8284409SSoren Brinkmann label = "EP108"; 280c8284409SSoren Brinkmann break; 281c8284409SSoren Brinkmann case ZYNQMP_CSU_VERSION_QEMU: 282c8284409SSoren Brinkmann label = "QEMU"; 283c8284409SSoren Brinkmann break; 284c8284409SSoren Brinkmann case ZYNQMP_CSU_VERSION_SILICON: 285c8284409SSoren Brinkmann label = "silicon"; 286c8284409SSoren Brinkmann break; 287649c48f5SJonathan Wright default: 288649c48f5SJonathan Wright /* Do nothing in default case */ 289649c48f5SJonathan Wright break; 290c8284409SSoren Brinkmann } 291c8284409SSoren Brinkmann 292*a6d28520SSiva Durga Prasad Paladugu NOTICE("ATF running on XCZU%s/%s v%d/RTL%d.%d at 0x%x\n", 293c8284409SSoren Brinkmann zynqmp_print_silicon_idcode(), label, zynqmp_get_ps_ver(), 294*a6d28520SSiva Durga Prasad Paladugu (rtl & 0xf0) >> 4, rtl & 0xf, BL31_BASE); 295c8284409SSoren Brinkmann } 296c8284409SSoren Brinkmann #else 297c8284409SSoren Brinkmann static inline void zynqmp_print_platform_name(void) { } 298c8284409SSoren Brinkmann #endif 299c8284409SSoren Brinkmann 3002cb5bac9SSoren Brinkmann unsigned int zynqmp_get_bootmode(void) 3012cb5bac9SSoren Brinkmann { 30229bd0e66SSiva Durga Prasad Paladugu uint32_t r; 303*a6d28520SSiva Durga Prasad Paladugu unsigned int ret; 30429bd0e66SSiva Durga Prasad Paladugu 305*a6d28520SSiva Durga Prasad Paladugu ret = pm_mmio_read(CRL_APB_BOOT_MODE_USER, &r); 306*a6d28520SSiva Durga Prasad Paladugu 307*a6d28520SSiva Durga Prasad Paladugu if (ret != PM_RET_SUCCESS) 30829bd0e66SSiva Durga Prasad Paladugu r = mmio_read_32(CRL_APB_BOOT_MODE_USER); 3092cb5bac9SSoren Brinkmann 3102cb5bac9SSoren Brinkmann return r & CRL_APB_BOOT_MODE_MASK; 3112cb5bac9SSoren Brinkmann } 3122cb5bac9SSoren Brinkmann 313c8284409SSoren Brinkmann void zynqmp_config_setup(void) 314c8284409SSoren Brinkmann { 315c8284409SSoren Brinkmann zynqmp_print_platform_name(); 316e1cb4da4SSoren Brinkmann generic_delay_timer_init(); 317c8284409SSoren Brinkmann } 318c8284409SSoren Brinkmann 319f3d3b316SAntonio Nino Diaz unsigned int plat_get_syscnt_freq2(void) 320c8284409SSoren Brinkmann { 321e89f4af7SSoren Brinkmann unsigned int ver = zynqmp_get_silicon_ver(); 322c8284409SSoren Brinkmann 323e89f4af7SSoren Brinkmann switch (ver) { 324e89f4af7SSoren Brinkmann case ZYNQMP_CSU_VERSION_VELOCE: 325e89f4af7SSoren Brinkmann return 10000; 326e89f4af7SSoren Brinkmann case ZYNQMP_CSU_VERSION_EP108: 327e89f4af7SSoren Brinkmann return 4000000; 328e89f4af7SSoren Brinkmann case ZYNQMP_CSU_VERSION_QEMU: 329e89f4af7SSoren Brinkmann return 50000000; 330649c48f5SJonathan Wright default: 331649c48f5SJonathan Wright /* Do nothing in default case */ 332649c48f5SJonathan Wright break; 333e89f4af7SSoren Brinkmann } 334c8284409SSoren Brinkmann 335e89f4af7SSoren Brinkmann return mmio_read_32(IOU_SCNTRS_BASEFREQ); 336c8284409SSoren Brinkmann } 337