zynqmp.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2014 - 2015 Xilinx, Inc.
  4. * Michal Simek <michal.simek@xilinx.com>
  5. */
  6. #include <common.h>
  7. #include <command.h>
  8. #include <cpu_func.h>
  9. #include <debug_uart.h>
  10. #include <env.h>
  11. #include <env_internal.h>
  12. #include <init.h>
  13. #include <log.h>
  14. #include <net.h>
  15. #include <sata.h>
  16. #include <ahci.h>
  17. #include <scsi.h>
  18. #include <malloc.h>
  19. #include <wdt.h>
  20. #include <asm/arch/clk.h>
  21. #include <asm/arch/hardware.h>
  22. #include <asm/arch/sys_proto.h>
  23. #include <asm/arch/psu_init_gpl.h>
  24. #include <asm/cache.h>
  25. #include <asm/io.h>
  26. #include <asm/ptrace.h>
  27. #include <dm/device.h>
  28. #include <dm/uclass.h>
  29. #include <usb.h>
  30. #include <dwc3-uboot.h>
  31. #include <zynqmppl.h>
  32. #include <zynqmp_firmware.h>
  33. #include <g_dnl.h>
  34. #include <linux/bitops.h>
  35. #include <linux/delay.h>
  36. #include <linux/sizes.h>
  37. #include "../common/board.h"
  38. #include "pm_cfg_obj.h"
  39. #define ZYNQMP_VERSION_SIZE 7
  40. #define EFUSE_VCU_DIS_MASK 0x100
  41. #define EFUSE_VCU_DIS_SHIFT 8
  42. #define EFUSE_GPU_DIS_MASK 0x20
  43. #define EFUSE_GPU_DIS_SHIFT 5
  44. #define IDCODE2_PL_INIT_MASK 0x200
  45. #define IDCODE2_PL_INIT_SHIFT 9
  46. DECLARE_GLOBAL_DATA_PTR;
  47. #if CONFIG_IS_ENABLED(FPGA) && defined(CONFIG_FPGA_ZYNQMPPL)
  48. static xilinx_desc zynqmppl = XILINX_ZYNQMP_DESC;
  49. enum {
  50. ZYNQMP_VARIANT_EG = BIT(0U),
  51. ZYNQMP_VARIANT_EV = BIT(1U),
  52. ZYNQMP_VARIANT_CG = BIT(2U),
  53. ZYNQMP_VARIANT_DR = BIT(3U),
  54. };
  55. static const struct {
  56. u32 id;
  57. u8 device;
  58. u8 variants;
  59. } zynqmp_devices[] = {
  60. {
  61. .id = 0x04711093,
  62. .device = 2,
  63. .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG,
  64. },
  65. {
  66. .id = 0x04710093,
  67. .device = 3,
  68. .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG,
  69. },
  70. {
  71. .id = 0x04721093,
  72. .device = 4,
  73. .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG |
  74. ZYNQMP_VARIANT_EV,
  75. },
  76. {
  77. .id = 0x04720093,
  78. .device = 5,
  79. .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG |
  80. ZYNQMP_VARIANT_EV,
  81. },
  82. {
  83. .id = 0x04739093,
  84. .device = 6,
  85. .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG,
  86. },
  87. {
  88. .id = 0x04730093,
  89. .device = 7,
  90. .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG |
  91. ZYNQMP_VARIANT_EV,
  92. },
  93. {
  94. .id = 0x04738093,
  95. .device = 9,
  96. .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG,
  97. },
  98. {
  99. .id = 0x04740093,
  100. .device = 11,
  101. .variants = ZYNQMP_VARIANT_EG,
  102. },
  103. {
  104. .id = 0x04750093,
  105. .device = 15,
  106. .variants = ZYNQMP_VARIANT_EG,
  107. },
  108. {
  109. .id = 0x04759093,
  110. .device = 17,
  111. .variants = ZYNQMP_VARIANT_EG,
  112. },
  113. {
  114. .id = 0x04758093,
  115. .device = 19,
  116. .variants = ZYNQMP_VARIANT_EG,
  117. },
  118. {
  119. .id = 0x047E1093,
  120. .device = 21,
  121. .variants = ZYNQMP_VARIANT_DR,
  122. },
  123. {
  124. .id = 0x047E3093,
  125. .device = 23,
  126. .variants = ZYNQMP_VARIANT_DR,
  127. },
  128. {
  129. .id = 0x047E5093,
  130. .device = 25,
  131. .variants = ZYNQMP_VARIANT_DR,
  132. },
  133. {
  134. .id = 0x047E4093,
  135. .device = 27,
  136. .variants = ZYNQMP_VARIANT_DR,
  137. },
  138. {
  139. .id = 0x047E0093,
  140. .device = 28,
  141. .variants = ZYNQMP_VARIANT_DR,
  142. },
  143. {
  144. .id = 0x047E2093,
  145. .device = 29,
  146. .variants = ZYNQMP_VARIANT_DR,
  147. },
  148. {
  149. .id = 0x047E6093,
  150. .device = 39,
  151. .variants = ZYNQMP_VARIANT_DR,
  152. },
  153. {
  154. .id = 0x047FD093,
  155. .device = 43,
  156. .variants = ZYNQMP_VARIANT_DR,
  157. },
  158. {
  159. .id = 0x047F8093,
  160. .device = 46,
  161. .variants = ZYNQMP_VARIANT_DR,
  162. },
  163. {
  164. .id = 0x047FF093,
  165. .device = 47,
  166. .variants = ZYNQMP_VARIANT_DR,
  167. },
  168. {
  169. .id = 0x047FB093,
  170. .device = 48,
  171. .variants = ZYNQMP_VARIANT_DR,
  172. },
  173. {
  174. .id = 0x047FE093,
  175. .device = 49,
  176. .variants = ZYNQMP_VARIANT_DR,
  177. },
  178. };
  179. static char *zynqmp_get_silicon_idcode_name(void)
  180. {
  181. u32 i;
  182. u32 idcode, idcode2;
  183. char name[ZYNQMP_VERSION_SIZE];
  184. u32 ret_payload[PAYLOAD_ARG_CNT];
  185. int ret;
  186. ret = xilinx_pm_request(PM_GET_CHIPID, 0, 0, 0, 0, ret_payload);
  187. if (ret) {
  188. debug("%s: Getting chipid failed\n", __func__);
  189. return "unknown";
  190. }
  191. /*
  192. * Firmware returns:
  193. * payload[0][31:0] = status of the operation
  194. * payload[1]] = IDCODE
  195. * payload[2][19:0] = Version
  196. * payload[2][28:20] = EXTENDED_IDCODE
  197. * payload[2][29] = PL_INIT
  198. */
  199. idcode = ret_payload[1];
  200. idcode2 = ret_payload[2] >> ZYNQMP_CSU_VERSION_EMPTY_SHIFT;
  201. debug("%s, IDCODE: 0x%0x, IDCODE2: 0x%0x\r\n", __func__, idcode,
  202. idcode2);
  203. for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
  204. if (zynqmp_devices[i].id == (idcode & 0x0FFFFFFF))
  205. break;
  206. }
  207. if (i >= ARRAY_SIZE(zynqmp_devices))
  208. return "unknown";
  209. /* Add device prefix to the name */
  210. ret = snprintf(name, ZYNQMP_VERSION_SIZE, "zu%d",
  211. zynqmp_devices[i].device);
  212. if (ret < 0)
  213. return "unknown";
  214. if (zynqmp_devices[i].variants & ZYNQMP_VARIANT_EV) {
  215. /* Devices with EV variant might be EG/CG/EV family */
  216. if (idcode2 & IDCODE2_PL_INIT_MASK) {
  217. u32 family = ((idcode2 & EFUSE_VCU_DIS_MASK) >>
  218. EFUSE_VCU_DIS_SHIFT) << 1 |
  219. ((idcode2 & EFUSE_GPU_DIS_MASK) >>
  220. EFUSE_GPU_DIS_SHIFT);
  221. /*
  222. * Get family name based on extended idcode values as
  223. * determined on UG1087, EXTENDED_IDCODE register
  224. * description
  225. */
  226. switch (family) {
  227. case 0x00:
  228. strncat(name, "ev", 2);
  229. break;
  230. case 0x10:
  231. strncat(name, "eg", 2);
  232. break;
  233. case 0x11:
  234. strncat(name, "cg", 2);
  235. break;
  236. default:
  237. /* Do not append family name*/
  238. break;
  239. }
  240. } else {
  241. /*
  242. * When PL powered down the VCU Disable efuse cannot be
  243. * read. So, ignore the bit and just findout if it is CG
  244. * or EG/EV variant.
  245. */
  246. strncat(name, (idcode2 & EFUSE_GPU_DIS_MASK) ? "cg" :
  247. "e", 2);
  248. }
  249. } else if (zynqmp_devices[i].variants & ZYNQMP_VARIANT_CG) {
  250. /* Devices with CG variant might be EG or CG family */
  251. strncat(name, (idcode2 & EFUSE_GPU_DIS_MASK) ? "cg" : "eg", 2);
  252. } else if (zynqmp_devices[i].variants & ZYNQMP_VARIANT_EG) {
  253. strncat(name, "eg", 2);
  254. } else if (zynqmp_devices[i].variants & ZYNQMP_VARIANT_DR) {
  255. strncat(name, "dr", 2);
  256. } else {
  257. debug("Variant not identified\n");
  258. }
  259. return strdup(name);
  260. }
  261. #endif
  262. int board_early_init_f(void)
  263. {
  264. #if defined(CONFIG_ZYNQMP_PSU_INIT_ENABLED)
  265. int ret;
  266. ret = psu_init();
  267. if (ret)
  268. return ret;
  269. /* Delay is required for clocks to be propagated */
  270. udelay(1000000);
  271. #endif
  272. #ifdef CONFIG_DEBUG_UART
  273. /* Uart debug for sure */
  274. debug_uart_init();
  275. puts("Debug uart enabled\n"); /* or printch() */
  276. #endif
  277. return 0;
  278. }
  279. static int multi_boot(void)
  280. {
  281. u32 multiboot;
  282. multiboot = readl(&csu_base->multi_boot);
  283. printf("Multiboot:\t%d\n", multiboot);
  284. return 0;
  285. }
  286. #define PS_SYSMON_ANALOG_BUS_VAL 0x3210
  287. #define PS_SYSMON_ANALOG_BUS_REG 0xFFA50914
  288. int board_init(void)
  289. {
  290. #if defined(CONFIG_ZYNQMP_FIRMWARE)
  291. struct udevice *dev;
  292. uclass_get_device_by_name(UCLASS_FIRMWARE, "zynqmp-power", &dev);
  293. if (!dev)
  294. panic("PMU Firmware device not found - Enable it");
  295. #endif
  296. #if defined(CONFIG_SPL_BUILD)
  297. /* Check *at build time* if the filename is an non-empty string */
  298. if (sizeof(CONFIG_ZYNQMP_SPL_PM_CFG_OBJ_FILE) > 1)
  299. zynqmp_pmufw_load_config_object(zynqmp_pm_cfg_obj,
  300. zynqmp_pm_cfg_obj_size);
  301. #else
  302. if (CONFIG_IS_ENABLED(DM_I2C) && CONFIG_IS_ENABLED(I2C_EEPROM))
  303. xilinx_read_eeprom();
  304. #endif
  305. printf("EL Level:\tEL%d\n", current_el());
  306. /* Bug in ROM sets wrong value in this register */
  307. writel(PS_SYSMON_ANALOG_BUS_VAL, PS_SYSMON_ANALOG_BUS_REG);
  308. #if CONFIG_IS_ENABLED(FPGA) && defined(CONFIG_FPGA_ZYNQMPPL)
  309. zynqmppl.name = zynqmp_get_silicon_idcode_name();
  310. printf("Chip ID:\t%s\n", zynqmppl.name);
  311. fpga_init();
  312. fpga_add(fpga_xilinx, &zynqmppl);
  313. #endif
  314. if (current_el() == 3)
  315. multi_boot();
  316. return 0;
  317. }
  318. int board_early_init_r(void)
  319. {
  320. u32 val;
  321. if (current_el() != 3)
  322. return 0;
  323. val = readl(&crlapb_base->timestamp_ref_ctrl);
  324. val &= ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT;
  325. if (!val) {
  326. val = readl(&crlapb_base->timestamp_ref_ctrl);
  327. val |= ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT;
  328. writel(val, &crlapb_base->timestamp_ref_ctrl);
  329. /* Program freq register in System counter */
  330. writel(zynqmp_get_system_timer_freq(),
  331. &iou_scntr_secure->base_frequency_id_register);
  332. /* And enable system counter */
  333. writel(ZYNQMP_IOU_SCNTR_COUNTER_CONTROL_REGISTER_EN,
  334. &iou_scntr_secure->counter_control_register);
  335. }
  336. return 0;
  337. }
  338. unsigned long do_go_exec(ulong (*entry)(int, char * const []), int argc,
  339. char *const argv[])
  340. {
  341. int ret = 0;
  342. if (current_el() > 1) {
  343. smp_kick_all_cpus();
  344. dcache_disable();
  345. armv8_switch_to_el1(0x0, 0, 0, 0, (unsigned long)entry,
  346. ES_TO_AARCH64);
  347. } else {
  348. printf("FAIL: current EL is not above EL1\n");
  349. ret = EINVAL;
  350. }
  351. return ret;
  352. }
  353. #if !defined(CONFIG_SYS_SDRAM_BASE) && !defined(CONFIG_SYS_SDRAM_SIZE)
  354. int dram_init_banksize(void)
  355. {
  356. int ret;
  357. ret = fdtdec_setup_memory_banksize();
  358. if (ret)
  359. return ret;
  360. mem_map_fill();
  361. return 0;
  362. }
  363. int dram_init(void)
  364. {
  365. if (fdtdec_setup_mem_size_base() != 0)
  366. return -EINVAL;
  367. return 0;
  368. }
  369. #else
  370. int dram_init_banksize(void)
  371. {
  372. gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
  373. gd->bd->bi_dram[0].size = get_effective_memsize();
  374. mem_map_fill();
  375. return 0;
  376. }
  377. int dram_init(void)
  378. {
  379. gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
  380. CONFIG_SYS_SDRAM_SIZE);
  381. return 0;
  382. }
  383. #endif
  384. void reset_cpu(ulong addr)
  385. {
  386. }
  387. static u8 __maybe_unused zynqmp_get_bootmode(void)
  388. {
  389. u8 bootmode;
  390. u32 reg = 0;
  391. int ret;
  392. ret = zynqmp_mmio_read((ulong)&crlapb_base->boot_mode, &reg);
  393. if (ret)
  394. return -EINVAL;
  395. if (reg >> BOOT_MODE_ALT_SHIFT)
  396. reg >>= BOOT_MODE_ALT_SHIFT;
  397. bootmode = reg & BOOT_MODES_MASK;
  398. return bootmode;
  399. }
  400. #if defined(CONFIG_BOARD_LATE_INIT)
  401. static const struct {
  402. u32 bit;
  403. const char *name;
  404. } reset_reasons[] = {
  405. { RESET_REASON_DEBUG_SYS, "DEBUG" },
  406. { RESET_REASON_SOFT, "SOFT" },
  407. { RESET_REASON_SRST, "SRST" },
  408. { RESET_REASON_PSONLY, "PS-ONLY" },
  409. { RESET_REASON_PMU, "PMU" },
  410. { RESET_REASON_INTERNAL, "INTERNAL" },
  411. { RESET_REASON_EXTERNAL, "EXTERNAL" },
  412. {}
  413. };
  414. static int reset_reason(void)
  415. {
  416. u32 reg;
  417. int i, ret;
  418. const char *reason = NULL;
  419. ret = zynqmp_mmio_read((ulong)&crlapb_base->reset_reason, &reg);
  420. if (ret)
  421. return -EINVAL;
  422. puts("Reset reason:\t");
  423. for (i = 0; i < ARRAY_SIZE(reset_reasons); i++) {
  424. if (reg & reset_reasons[i].bit) {
  425. reason = reset_reasons[i].name;
  426. printf("%s ", reset_reasons[i].name);
  427. break;
  428. }
  429. }
  430. puts("\n");
  431. env_set("reset_reason", reason);
  432. ret = zynqmp_mmio_write((ulong)&crlapb_base->reset_reason, ~0, ~0);
  433. if (ret)
  434. return -EINVAL;
  435. return ret;
  436. }
  437. static int set_fdtfile(void)
  438. {
  439. char *compatible, *fdtfile;
  440. const char *suffix = ".dtb";
  441. const char *vendor = "xilinx/";
  442. int fdt_compat_len;
  443. if (env_get("fdtfile"))
  444. return 0;
  445. compatible = (char *)fdt_getprop(gd->fdt_blob, 0, "compatible",
  446. &fdt_compat_len);
  447. if (compatible && fdt_compat_len) {
  448. char *name;
  449. debug("Compatible: %s\n", compatible);
  450. name = strchr(compatible, ',');
  451. if (!name)
  452. return -EINVAL;
  453. name++;
  454. fdtfile = calloc(1, strlen(vendor) + strlen(name) +
  455. strlen(suffix) + 1);
  456. if (!fdtfile)
  457. return -ENOMEM;
  458. sprintf(fdtfile, "%s%s%s", vendor, name, suffix);
  459. env_set("fdtfile", fdtfile);
  460. free(fdtfile);
  461. }
  462. return 0;
  463. }
  464. int board_late_init(void)
  465. {
  466. u8 bootmode;
  467. struct udevice *dev;
  468. int bootseq = -1;
  469. int bootseq_len = 0;
  470. int env_targets_len = 0;
  471. const char *mode;
  472. char *new_targets;
  473. char *env_targets;
  474. int ret;
  475. #if defined(CONFIG_USB_ETHER) && !defined(CONFIG_USB_GADGET_DOWNLOAD)
  476. usb_ether_init();
  477. #endif
  478. if (!(gd->flags & GD_FLG_ENV_DEFAULT)) {
  479. debug("Saved variables - Skipping\n");
  480. return 0;
  481. }
  482. if (!CONFIG_IS_ENABLED(ENV_VARS_UBOOT_RUNTIME_CONFIG))
  483. return 0;
  484. ret = set_fdtfile();
  485. if (ret)
  486. return ret;
  487. bootmode = zynqmp_get_bootmode();
  488. puts("Bootmode: ");
  489. switch (bootmode) {
  490. case USB_MODE:
  491. puts("USB_MODE\n");
  492. mode = "usb";
  493. env_set("modeboot", "usb_dfu_spl");
  494. break;
  495. case JTAG_MODE:
  496. puts("JTAG_MODE\n");
  497. mode = "jtag pxe dhcp";
  498. env_set("modeboot", "jtagboot");
  499. break;
  500. case QSPI_MODE_24BIT:
  501. case QSPI_MODE_32BIT:
  502. mode = "qspi0";
  503. puts("QSPI_MODE\n");
  504. env_set("modeboot", "qspiboot");
  505. break;
  506. case EMMC_MODE:
  507. puts("EMMC_MODE\n");
  508. if (uclass_get_device_by_name(UCLASS_MMC,
  509. "mmc@ff160000", &dev) &&
  510. uclass_get_device_by_name(UCLASS_MMC,
  511. "sdhci@ff160000", &dev)) {
  512. puts("Boot from EMMC but without SD0 enabled!\n");
  513. return -1;
  514. }
  515. debug("mmc0 device found at %p, seq %d\n", dev, dev_seq(dev));
  516. mode = "mmc";
  517. bootseq = dev_seq(dev);
  518. break;
  519. case SD_MODE:
  520. puts("SD_MODE\n");
  521. if (uclass_get_device_by_name(UCLASS_MMC,
  522. "mmc@ff160000", &dev) &&
  523. uclass_get_device_by_name(UCLASS_MMC,
  524. "sdhci@ff160000", &dev)) {
  525. puts("Boot from SD0 but without SD0 enabled!\n");
  526. return -1;
  527. }
  528. debug("mmc0 device found at %p, seq %d\n", dev, dev_seq(dev));
  529. mode = "mmc";
  530. bootseq = dev_seq(dev);
  531. env_set("modeboot", "sdboot");
  532. break;
  533. case SD1_LSHFT_MODE:
  534. puts("LVL_SHFT_");
  535. /* fall through */
  536. case SD_MODE1:
  537. puts("SD_MODE1\n");
  538. if (uclass_get_device_by_name(UCLASS_MMC,
  539. "mmc@ff170000", &dev) &&
  540. uclass_get_device_by_name(UCLASS_MMC,
  541. "sdhci@ff170000", &dev)) {
  542. puts("Boot from SD1 but without SD1 enabled!\n");
  543. return -1;
  544. }
  545. debug("mmc1 device found at %p, seq %d\n", dev, dev_seq(dev));
  546. mode = "mmc";
  547. bootseq = dev_seq(dev);
  548. env_set("modeboot", "sdboot");
  549. break;
  550. case NAND_MODE:
  551. puts("NAND_MODE\n");
  552. mode = "nand0";
  553. env_set("modeboot", "nandboot");
  554. break;
  555. default:
  556. mode = "";
  557. printf("Invalid Boot Mode:0x%x\n", bootmode);
  558. break;
  559. }
  560. if (bootseq >= 0) {
  561. bootseq_len = snprintf(NULL, 0, "%i", bootseq);
  562. debug("Bootseq len: %x\n", bootseq_len);
  563. }
  564. /*
  565. * One terminating char + one byte for space between mode
  566. * and default boot_targets
  567. */
  568. env_targets = env_get("boot_targets");
  569. if (env_targets)
  570. env_targets_len = strlen(env_targets);
  571. new_targets = calloc(1, strlen(mode) + env_targets_len + 2 +
  572. bootseq_len);
  573. if (!new_targets)
  574. return -ENOMEM;
  575. if (bootseq >= 0)
  576. sprintf(new_targets, "%s%x %s", mode, bootseq,
  577. env_targets ? env_targets : "");
  578. else
  579. sprintf(new_targets, "%s %s", mode,
  580. env_targets ? env_targets : "");
  581. env_set("boot_targets", new_targets);
  582. reset_reason();
  583. return board_late_init_xilinx();
  584. }
  585. #endif
  586. int checkboard(void)
  587. {
  588. puts("Board: Xilinx ZynqMP\n");
  589. return 0;
  590. }
  591. enum env_location env_get_location(enum env_operation op, int prio)
  592. {
  593. u32 bootmode = zynqmp_get_bootmode();
  594. if (prio)
  595. return ENVL_UNKNOWN;
  596. switch (bootmode) {
  597. case EMMC_MODE:
  598. case SD_MODE:
  599. case SD1_LSHFT_MODE:
  600. case SD_MODE1:
  601. if (IS_ENABLED(CONFIG_ENV_IS_IN_FAT))
  602. return ENVL_FAT;
  603. if (IS_ENABLED(CONFIG_ENV_IS_IN_EXT4))
  604. return ENVL_EXT4;
  605. return ENVL_UNKNOWN;
  606. case NAND_MODE:
  607. if (IS_ENABLED(CONFIG_ENV_IS_IN_NAND))
  608. return ENVL_NAND;
  609. if (IS_ENABLED(CONFIG_ENV_IS_IN_UBI))
  610. return ENVL_UBI;
  611. return ENVL_UNKNOWN;
  612. case QSPI_MODE_24BIT:
  613. case QSPI_MODE_32BIT:
  614. if (IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH))
  615. return ENVL_SPI_FLASH;
  616. return ENVL_UNKNOWN;
  617. case JTAG_MODE:
  618. default:
  619. return ENVL_NOWHERE;
  620. }
  621. }