1 /* 2 * (C) Copyright 2014 - 2015 Xilinx, Inc. 3 * Michal Simek <michal.simek@xilinx.com> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 #include <sata.h> 10 #include <ahci.h> 11 #include <scsi.h> 12 #include <malloc.h> 13 #include <asm/arch/clk.h> 14 #include <asm/arch/hardware.h> 15 #include <asm/arch/sys_proto.h> 16 #include <asm/io.h> 17 #include <usb.h> 18 #include <dwc3-uboot.h> 19 #include <zynqmppl.h> 20 #include <i2c.h> 21 #include <g_dnl.h> 22 23 DECLARE_GLOBAL_DATA_PTR; 24 25 #if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \ 26 !defined(CONFIG_SPL_BUILD) 27 static xilinx_desc zynqmppl = XILINX_ZYNQMP_DESC; 28 29 static const struct { 30 uint32_t id; 31 char *name; 32 } zynqmp_devices[] = { 33 { 34 .id = 0x10, 35 .name = "3eg", 36 }, 37 { 38 .id = 0x11, 39 .name = "2eg", 40 }, 41 { 42 .id = 0x20, 43 .name = "5ev", 44 }, 45 { 46 .id = 0x21, 47 .name = "4ev", 48 }, 49 { 50 .id = 0x30, 51 .name = "7ev", 52 }, 53 { 54 .id = 0x38, 55 .name = "9eg", 56 }, 57 { 58 .id = 0x39, 59 .name = "6eg", 60 }, 61 { 62 .id = 0x40, 63 .name = "11eg", 64 }, 65 { 66 .id = 0x50, 67 .name = "15eg", 68 }, 69 { 70 .id = 0x58, 71 .name = "19eg", 72 }, 73 { 74 .id = 0x59, 75 .name = "17eg", 76 }, 77 }; 78 #endif 79 80 int chip_id(unsigned char id) 81 { 82 struct pt_regs regs; 83 int val = -EINVAL; 84 85 if (current_el() != 3) { 86 regs.regs[0] = ZYNQMP_SIP_SVC_CSU_DMA_CHIPID; 87 regs.regs[1] = 0; 88 regs.regs[2] = 0; 89 regs.regs[3] = 0; 90 91 smc_call(®s); 92 93 /* 94 * SMC returns: 95 * regs[0][31:0] = status of the operation 96 * regs[0][63:32] = CSU.IDCODE register 97 * regs[1][31:0] = CSU.version register 98 */ 99 switch (id) { 100 case IDCODE: 101 regs.regs[0] = upper_32_bits(regs.regs[0]); 102 regs.regs[0] &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK | 103 ZYNQMP_CSU_IDCODE_SVD_MASK; 104 regs.regs[0] >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT; 105 val = regs.regs[0]; 106 break; 107 case VERSION: 108 regs.regs[1] = lower_32_bits(regs.regs[1]); 109 regs.regs[1] &= ZYNQMP_CSU_SILICON_VER_MASK; 110 val = regs.regs[1]; 111 break; 112 default: 113 printf("%s, Invalid Req:0x%x\n", __func__, id); 114 } 115 } else { 116 switch (id) { 117 case IDCODE: 118 val = readl(ZYNQMP_CSU_IDCODE_ADDR); 119 val &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK | 120 ZYNQMP_CSU_IDCODE_SVD_MASK; 121 val >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT; 122 break; 123 case VERSION: 124 val = readl(ZYNQMP_CSU_VER_ADDR); 125 val &= ZYNQMP_CSU_SILICON_VER_MASK; 126 break; 127 default: 128 printf("%s, Invalid Req:0x%x\n", __func__, id); 129 } 130 } 131 132 return val; 133 } 134 135 #if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \ 136 !defined(CONFIG_SPL_BUILD) 137 static char *zynqmp_get_silicon_idcode_name(void) 138 { 139 uint32_t i, id; 140 141 id = chip_id(IDCODE); 142 for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) { 143 if (zynqmp_devices[i].id == id) 144 return zynqmp_devices[i].name; 145 } 146 return "unknown"; 147 } 148 #endif 149 150 int board_early_init_f(void) 151 { 152 #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_CLK_ZYNQMP) 153 zynqmp_pmufw_version(); 154 #endif 155 156 #if defined(CONFIG_SPL_BUILD) || defined(CONFIG_ZYNQMP_PSU_INIT_ENABLED) 157 psu_init(); 158 #endif 159 160 return 0; 161 } 162 163 #define ZYNQMP_VERSION_SIZE 9 164 165 int board_init(void) 166 { 167 printf("EL Level:\tEL%d\n", current_el()); 168 169 #if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \ 170 !defined(CONFIG_SPL_BUILD) || (defined(CONFIG_SPL_FPGA_SUPPORT) && \ 171 defined(CONFIG_SPL_BUILD)) 172 if (current_el() != 3) { 173 static char version[ZYNQMP_VERSION_SIZE]; 174 175 strncat(version, "xczu", 4); 176 zynqmppl.name = strncat(version, 177 zynqmp_get_silicon_idcode_name(), 178 ZYNQMP_VERSION_SIZE - 5); 179 printf("Chip ID:\t%s\n", zynqmppl.name); 180 fpga_init(); 181 fpga_add(fpga_xilinx, &zynqmppl); 182 } 183 #endif 184 185 return 0; 186 } 187 188 int board_early_init_r(void) 189 { 190 u32 val; 191 192 val = readl(&crlapb_base->timestamp_ref_ctrl); 193 val &= ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT; 194 195 if (current_el() == 3 && !val) { 196 val = readl(&crlapb_base->timestamp_ref_ctrl); 197 val |= ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT; 198 writel(val, &crlapb_base->timestamp_ref_ctrl); 199 200 /* Program freq register in System counter */ 201 writel(zynqmp_get_system_timer_freq(), 202 &iou_scntr_secure->base_frequency_id_register); 203 /* And enable system counter */ 204 writel(ZYNQMP_IOU_SCNTR_COUNTER_CONTROL_REGISTER_EN, 205 &iou_scntr_secure->counter_control_register); 206 } 207 return 0; 208 } 209 210 int zynq_board_read_rom_ethaddr(unsigned char *ethaddr) 211 { 212 #if defined(CONFIG_ZYNQ_GEM_EEPROM_ADDR) && \ 213 defined(CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET) && \ 214 defined(CONFIG_ZYNQ_EEPROM_BUS) 215 i2c_set_bus_num(CONFIG_ZYNQ_EEPROM_BUS); 216 217 if (eeprom_read(CONFIG_ZYNQ_GEM_EEPROM_ADDR, 218 CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET, 219 ethaddr, 6)) 220 printf("I2C EEPROM MAC address read failed\n"); 221 #endif 222 223 return 0; 224 } 225 226 #if !defined(CONFIG_SYS_SDRAM_BASE) && !defined(CONFIG_SYS_SDRAM_SIZE) 227 int dram_init_banksize(void) 228 { 229 fdtdec_setup_memory_banksize(); 230 231 return 0; 232 } 233 234 int dram_init(void) 235 { 236 if (fdtdec_setup_memory_size() != 0) 237 return -EINVAL; 238 239 return 0; 240 } 241 #else 242 int dram_init(void) 243 { 244 gd->ram_size = CONFIG_SYS_SDRAM_SIZE; 245 246 return 0; 247 } 248 #endif 249 250 void reset_cpu(ulong addr) 251 { 252 } 253 254 int board_late_init(void) 255 { 256 u32 reg = 0; 257 u8 bootmode; 258 const char *mode; 259 char *new_targets; 260 261 if (!(gd->flags & GD_FLG_ENV_DEFAULT)) { 262 debug("Saved variables - Skipping\n"); 263 return 0; 264 } 265 266 reg = readl(&crlapb_base->boot_mode); 267 if (reg >> BOOT_MODE_ALT_SHIFT) 268 reg >>= BOOT_MODE_ALT_SHIFT; 269 270 bootmode = reg & BOOT_MODES_MASK; 271 272 puts("Bootmode: "); 273 switch (bootmode) { 274 case USB_MODE: 275 puts("USB_MODE\n"); 276 mode = "usb"; 277 break; 278 case JTAG_MODE: 279 puts("JTAG_MODE\n"); 280 mode = "pxe dhcp"; 281 break; 282 case QSPI_MODE_24BIT: 283 case QSPI_MODE_32BIT: 284 mode = "qspi0"; 285 puts("QSPI_MODE\n"); 286 break; 287 case EMMC_MODE: 288 puts("EMMC_MODE\n"); 289 mode = "mmc0"; 290 break; 291 case SD_MODE: 292 puts("SD_MODE\n"); 293 mode = "mmc0"; 294 break; 295 case SD1_LSHFT_MODE: 296 puts("LVL_SHFT_"); 297 /* fall through */ 298 case SD_MODE1: 299 puts("SD_MODE1\n"); 300 #if defined(CONFIG_ZYNQ_SDHCI0) && defined(CONFIG_ZYNQ_SDHCI1) 301 mode = "mmc1"; 302 #else 303 mode = "mmc0"; 304 #endif 305 break; 306 case NAND_MODE: 307 puts("NAND_MODE\n"); 308 mode = "nand0"; 309 break; 310 default: 311 mode = ""; 312 printf("Invalid Boot Mode:0x%x\n", bootmode); 313 break; 314 } 315 316 /* 317 * One terminating char + one byte for space between mode 318 * and default boot_targets 319 */ 320 new_targets = calloc(1, strlen(mode) + 321 strlen(getenv("boot_targets")) + 2); 322 323 sprintf(new_targets, "%s %s", mode, getenv("boot_targets")); 324 setenv("boot_targets", new_targets); 325 326 return 0; 327 } 328 329 int checkboard(void) 330 { 331 puts("Board: Xilinx ZynqMP\n"); 332 return 0; 333 } 334 335 #ifdef CONFIG_USB_DWC3 336 static struct dwc3_device dwc3_device_data0 = { 337 .maximum_speed = USB_SPEED_HIGH, 338 .base = ZYNQMP_USB0_XHCI_BASEADDR, 339 .dr_mode = USB_DR_MODE_PERIPHERAL, 340 .index = 0, 341 }; 342 343 static struct dwc3_device dwc3_device_data1 = { 344 .maximum_speed = USB_SPEED_HIGH, 345 .base = ZYNQMP_USB1_XHCI_BASEADDR, 346 .dr_mode = USB_DR_MODE_PERIPHERAL, 347 .index = 1, 348 }; 349 350 int usb_gadget_handle_interrupts(int index) 351 { 352 dwc3_uboot_handle_interrupt(index); 353 return 0; 354 } 355 356 int board_usb_init(int index, enum usb_init_type init) 357 { 358 debug("%s: index %x\n", __func__, index); 359 360 #if defined(CONFIG_USB_GADGET_DOWNLOAD) 361 g_dnl_set_serialnumber(CONFIG_SYS_CONFIG_NAME); 362 #endif 363 364 switch (index) { 365 case 0: 366 return dwc3_uboot_init(&dwc3_device_data0); 367 case 1: 368 return dwc3_uboot_init(&dwc3_device_data1); 369 }; 370 371 return -1; 372 } 373 374 int board_usb_cleanup(int index, enum usb_init_type init) 375 { 376 dwc3_uboot_exit(index); 377 return 0; 378 } 379 #endif 380