1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2014 - 2015 Xilinx, Inc. 4 * Michal Simek <michal.simek@xilinx.com> 5 */ 6 7 #include <common.h> 8 #include <sata.h> 9 #include <ahci.h> 10 #include <scsi.h> 11 #include <malloc.h> 12 #include <asm/arch/clk.h> 13 #include <asm/arch/hardware.h> 14 #include <asm/arch/sys_proto.h> 15 #include <asm/arch/psu_init_gpl.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 u32 id; 31 u32 ver; 32 char *name; 33 bool evexists; 34 } zynqmp_devices[] = { 35 { 36 .id = 0x10, 37 .name = "3eg", 38 }, 39 { 40 .id = 0x10, 41 .ver = 0x2c, 42 .name = "3cg", 43 }, 44 { 45 .id = 0x11, 46 .name = "2eg", 47 }, 48 { 49 .id = 0x11, 50 .ver = 0x2c, 51 .name = "2cg", 52 }, 53 { 54 .id = 0x20, 55 .name = "5ev", 56 .evexists = 1, 57 }, 58 { 59 .id = 0x20, 60 .ver = 0x100, 61 .name = "5eg", 62 .evexists = 1, 63 }, 64 { 65 .id = 0x20, 66 .ver = 0x12c, 67 .name = "5cg", 68 }, 69 { 70 .id = 0x21, 71 .name = "4ev", 72 .evexists = 1, 73 }, 74 { 75 .id = 0x21, 76 .ver = 0x100, 77 .name = "4eg", 78 .evexists = 1, 79 }, 80 { 81 .id = 0x21, 82 .ver = 0x12c, 83 .name = "4cg", 84 }, 85 { 86 .id = 0x30, 87 .name = "7ev", 88 .evexists = 1, 89 }, 90 { 91 .id = 0x30, 92 .ver = 0x100, 93 .name = "7eg", 94 .evexists = 1, 95 }, 96 { 97 .id = 0x30, 98 .ver = 0x12c, 99 .name = "7cg", 100 }, 101 { 102 .id = 0x38, 103 .name = "9eg", 104 }, 105 { 106 .id = 0x38, 107 .ver = 0x2c, 108 .name = "9cg", 109 }, 110 { 111 .id = 0x39, 112 .name = "6eg", 113 }, 114 { 115 .id = 0x39, 116 .ver = 0x2c, 117 .name = "6cg", 118 }, 119 { 120 .id = 0x40, 121 .name = "11eg", 122 }, 123 { /* For testing purpose only */ 124 .id = 0x50, 125 .ver = 0x2c, 126 .name = "15cg", 127 }, 128 { 129 .id = 0x50, 130 .name = "15eg", 131 }, 132 { 133 .id = 0x58, 134 .name = "19eg", 135 }, 136 { 137 .id = 0x59, 138 .name = "17eg", 139 }, 140 { 141 .id = 0x61, 142 .name = "21dr", 143 }, 144 { 145 .id = 0x63, 146 .name = "23dr", 147 }, 148 { 149 .id = 0x65, 150 .name = "25dr", 151 }, 152 { 153 .id = 0x64, 154 .name = "27dr", 155 }, 156 { 157 .id = 0x60, 158 .name = "28dr", 159 }, 160 { 161 .id = 0x62, 162 .name = "29dr", 163 }, 164 }; 165 #endif 166 167 int chip_id(unsigned char id) 168 { 169 struct pt_regs regs; 170 int val = -EINVAL; 171 172 if (current_el() != 3) { 173 regs.regs[0] = ZYNQMP_SIP_SVC_CSU_DMA_CHIPID; 174 regs.regs[1] = 0; 175 regs.regs[2] = 0; 176 regs.regs[3] = 0; 177 178 smc_call(®s); 179 180 /* 181 * SMC returns: 182 * regs[0][31:0] = status of the operation 183 * regs[0][63:32] = CSU.IDCODE register 184 * regs[1][31:0] = CSU.version register 185 * regs[1][63:32] = CSU.IDCODE2 register 186 */ 187 switch (id) { 188 case IDCODE: 189 regs.regs[0] = upper_32_bits(regs.regs[0]); 190 regs.regs[0] &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK | 191 ZYNQMP_CSU_IDCODE_SVD_MASK; 192 regs.regs[0] >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT; 193 val = regs.regs[0]; 194 break; 195 case VERSION: 196 regs.regs[1] = lower_32_bits(regs.regs[1]); 197 regs.regs[1] &= ZYNQMP_CSU_SILICON_VER_MASK; 198 val = regs.regs[1]; 199 break; 200 case IDCODE2: 201 regs.regs[1] = lower_32_bits(regs.regs[1]); 202 regs.regs[1] >>= ZYNQMP_CSU_VERSION_EMPTY_SHIFT; 203 val = regs.regs[1]; 204 break; 205 default: 206 printf("%s, Invalid Req:0x%x\n", __func__, id); 207 } 208 } else { 209 switch (id) { 210 case IDCODE: 211 val = readl(ZYNQMP_CSU_IDCODE_ADDR); 212 val &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK | 213 ZYNQMP_CSU_IDCODE_SVD_MASK; 214 val >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT; 215 break; 216 case VERSION: 217 val = readl(ZYNQMP_CSU_VER_ADDR); 218 val &= ZYNQMP_CSU_SILICON_VER_MASK; 219 break; 220 default: 221 printf("%s, Invalid Req:0x%x\n", __func__, id); 222 } 223 } 224 225 return val; 226 } 227 228 #define ZYNQMP_VERSION_SIZE 9 229 #define ZYNQMP_PL_STATUS_BIT 9 230 #define ZYNQMP_PL_STATUS_MASK BIT(ZYNQMP_PL_STATUS_BIT) 231 #define ZYNQMP_CSU_VERSION_MASK ~(ZYNQMP_PL_STATUS_MASK) 232 233 #if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \ 234 !defined(CONFIG_SPL_BUILD) 235 static char *zynqmp_get_silicon_idcode_name(void) 236 { 237 u32 i, id, ver; 238 char *buf; 239 static char name[ZYNQMP_VERSION_SIZE]; 240 241 id = chip_id(IDCODE); 242 ver = chip_id(IDCODE2); 243 244 for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) { 245 if ((zynqmp_devices[i].id == id) && 246 (zynqmp_devices[i].ver == (ver & 247 ZYNQMP_CSU_VERSION_MASK))) { 248 strncat(name, "zu", 2); 249 strncat(name, zynqmp_devices[i].name, 250 ZYNQMP_VERSION_SIZE - 3); 251 break; 252 } 253 } 254 255 if (i >= ARRAY_SIZE(zynqmp_devices)) 256 return "unknown"; 257 258 if (!zynqmp_devices[i].evexists) 259 return name; 260 261 if (ver & ZYNQMP_PL_STATUS_MASK) 262 return name; 263 264 if (strstr(name, "eg") || strstr(name, "ev")) { 265 buf = strstr(name, "e"); 266 *buf = '\0'; 267 } 268 269 return name; 270 } 271 #endif 272 273 int board_early_init_f(void) 274 { 275 int ret = 0; 276 #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_CLK_ZYNQMP) 277 zynqmp_pmufw_version(); 278 #endif 279 280 #if defined(CONFIG_ZYNQMP_PSU_INIT_ENABLED) 281 ret = psu_init(); 282 #endif 283 284 return ret; 285 } 286 287 int board_init(void) 288 { 289 printf("EL Level:\tEL%d\n", current_el()); 290 291 #if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \ 292 !defined(CONFIG_SPL_BUILD) || (defined(CONFIG_SPL_FPGA_SUPPORT) && \ 293 defined(CONFIG_SPL_BUILD)) 294 if (current_el() != 3) { 295 zynqmppl.name = zynqmp_get_silicon_idcode_name(); 296 printf("Chip ID:\t%s\n", zynqmppl.name); 297 fpga_init(); 298 fpga_add(fpga_xilinx, &zynqmppl); 299 } 300 #endif 301 302 return 0; 303 } 304 305 int board_early_init_r(void) 306 { 307 u32 val; 308 309 if (current_el() != 3) 310 return 0; 311 312 val = readl(&crlapb_base->timestamp_ref_ctrl); 313 val &= ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT; 314 315 if (!val) { 316 val = readl(&crlapb_base->timestamp_ref_ctrl); 317 val |= ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT; 318 writel(val, &crlapb_base->timestamp_ref_ctrl); 319 320 /* Program freq register in System counter */ 321 writel(zynqmp_get_system_timer_freq(), 322 &iou_scntr_secure->base_frequency_id_register); 323 /* And enable system counter */ 324 writel(ZYNQMP_IOU_SCNTR_COUNTER_CONTROL_REGISTER_EN, 325 &iou_scntr_secure->counter_control_register); 326 } 327 return 0; 328 } 329 330 int zynq_board_read_rom_ethaddr(unsigned char *ethaddr) 331 { 332 #if defined(CONFIG_ZYNQ_GEM_EEPROM_ADDR) && \ 333 defined(CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET) && \ 334 defined(CONFIG_ZYNQ_EEPROM_BUS) 335 i2c_set_bus_num(CONFIG_ZYNQ_EEPROM_BUS); 336 337 if (eeprom_read(CONFIG_ZYNQ_GEM_EEPROM_ADDR, 338 CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET, 339 ethaddr, 6)) 340 printf("I2C EEPROM MAC address read failed\n"); 341 #endif 342 343 return 0; 344 } 345 346 unsigned long do_go_exec(ulong (*entry)(int, char * const []), int argc, 347 char * const argv[]) 348 { 349 int ret = 0; 350 351 if (current_el() > 1) { 352 smp_kick_all_cpus(); 353 dcache_disable(); 354 armv8_switch_to_el1(0x0, 0, 0, 0, (unsigned long)entry, 355 ES_TO_AARCH64); 356 } else { 357 printf("FAIL: current EL is not above EL1\n"); 358 ret = EINVAL; 359 } 360 return ret; 361 } 362 363 #if !defined(CONFIG_SYS_SDRAM_BASE) && !defined(CONFIG_SYS_SDRAM_SIZE) 364 int dram_init_banksize(void) 365 { 366 return fdtdec_setup_memory_banksize(); 367 } 368 369 int dram_init(void) 370 { 371 if (fdtdec_setup_memory_size() != 0) 372 return -EINVAL; 373 374 return 0; 375 } 376 #else 377 int dram_init(void) 378 { 379 gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE, 380 CONFIG_SYS_SDRAM_SIZE); 381 382 return 0; 383 } 384 #endif 385 386 void reset_cpu(ulong addr) 387 { 388 } 389 390 int board_late_init(void) 391 { 392 u32 reg = 0; 393 u8 bootmode; 394 const char *mode; 395 char *new_targets; 396 char *env_targets; 397 int ret; 398 399 if (!(gd->flags & GD_FLG_ENV_DEFAULT)) { 400 debug("Saved variables - Skipping\n"); 401 return 0; 402 } 403 404 ret = zynqmp_mmio_read((ulong)&crlapb_base->boot_mode, ®); 405 if (ret) 406 return -EINVAL; 407 408 if (reg >> BOOT_MODE_ALT_SHIFT) 409 reg >>= BOOT_MODE_ALT_SHIFT; 410 411 bootmode = reg & BOOT_MODES_MASK; 412 413 puts("Bootmode: "); 414 switch (bootmode) { 415 case USB_MODE: 416 puts("USB_MODE\n"); 417 mode = "usb"; 418 env_set("modeboot", "usb_dfu_spl"); 419 break; 420 case JTAG_MODE: 421 puts("JTAG_MODE\n"); 422 mode = "pxe dhcp"; 423 env_set("modeboot", "jtagboot"); 424 break; 425 case QSPI_MODE_24BIT: 426 case QSPI_MODE_32BIT: 427 mode = "qspi0"; 428 puts("QSPI_MODE\n"); 429 env_set("modeboot", "qspiboot"); 430 break; 431 case EMMC_MODE: 432 puts("EMMC_MODE\n"); 433 mode = "mmc0"; 434 env_set("modeboot", "emmcboot"); 435 break; 436 case SD_MODE: 437 puts("SD_MODE\n"); 438 mode = "mmc0"; 439 env_set("modeboot", "sdboot"); 440 break; 441 case SD1_LSHFT_MODE: 442 puts("LVL_SHFT_"); 443 /* fall through */ 444 case SD_MODE1: 445 puts("SD_MODE1\n"); 446 #if defined(CONFIG_ZYNQ_SDHCI0) && defined(CONFIG_ZYNQ_SDHCI1) 447 mode = "mmc1"; 448 env_set("sdbootdev", "1"); 449 #else 450 mode = "mmc0"; 451 #endif 452 env_set("modeboot", "sdboot"); 453 break; 454 case NAND_MODE: 455 puts("NAND_MODE\n"); 456 mode = "nand0"; 457 env_set("modeboot", "nandboot"); 458 break; 459 default: 460 mode = ""; 461 printf("Invalid Boot Mode:0x%x\n", bootmode); 462 break; 463 } 464 465 /* 466 * One terminating char + one byte for space between mode 467 * and default boot_targets 468 */ 469 env_targets = env_get("boot_targets"); 470 if (env_targets) { 471 new_targets = calloc(1, strlen(mode) + 472 strlen(env_targets) + 2); 473 sprintf(new_targets, "%s %s", mode, env_targets); 474 } else { 475 new_targets = calloc(1, strlen(mode) + 2); 476 sprintf(new_targets, "%s", mode); 477 } 478 479 env_set("boot_targets", new_targets); 480 481 return 0; 482 } 483 484 int checkboard(void) 485 { 486 puts("Board: Xilinx ZynqMP\n"); 487 return 0; 488 } 489 490 #ifdef CONFIG_USB_DWC3 491 static struct dwc3_device dwc3_device_data0 = { 492 .maximum_speed = USB_SPEED_HIGH, 493 .base = ZYNQMP_USB0_XHCI_BASEADDR, 494 .dr_mode = USB_DR_MODE_PERIPHERAL, 495 .index = 0, 496 }; 497 498 static struct dwc3_device dwc3_device_data1 = { 499 .maximum_speed = USB_SPEED_HIGH, 500 .base = ZYNQMP_USB1_XHCI_BASEADDR, 501 .dr_mode = USB_DR_MODE_PERIPHERAL, 502 .index = 1, 503 }; 504 505 int usb_gadget_handle_interrupts(int index) 506 { 507 dwc3_uboot_handle_interrupt(index); 508 return 0; 509 } 510 511 int board_usb_init(int index, enum usb_init_type init) 512 { 513 debug("%s: index %x\n", __func__, index); 514 515 #if defined(CONFIG_USB_GADGET_DOWNLOAD) 516 g_dnl_set_serialnumber(CONFIG_SYS_CONFIG_NAME); 517 #endif 518 519 switch (index) { 520 case 0: 521 return dwc3_uboot_init(&dwc3_device_data0); 522 case 1: 523 return dwc3_uboot_init(&dwc3_device_data1); 524 }; 525 526 return -1; 527 } 528 529 int board_usb_cleanup(int index, enum usb_init_type init) 530 { 531 dwc3_uboot_exit(index); 532 return 0; 533 } 534 #endif 535