zynqmp.c 13 KB

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