board.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2018 Marvell International Ltd.
  4. *
  5. * https://spdx.org/licenses
  6. */
  7. #include <command.h>
  8. #include <console.h>
  9. #include <cpu_func.h>
  10. #include <dm.h>
  11. #include <asm/global_data.h>
  12. #include <dm/uclass-internal.h>
  13. #include <env.h>
  14. #include <init.h>
  15. #include <malloc.h>
  16. #include <net.h>
  17. #include <pci_ids.h>
  18. #include <errno.h>
  19. #include <asm/io.h>
  20. #include <linux/compiler.h>
  21. #include <linux/delay.h>
  22. #include <linux/libfdt.h>
  23. #include <fdt_support.h>
  24. #include <asm/arch/smc.h>
  25. #include <asm/arch/soc.h>
  26. #include <asm/arch/board.h>
  27. #include <dm/util.h>
  28. DECLARE_GLOBAL_DATA_PTR;
  29. void cleanup_env_ethaddr(void)
  30. {
  31. char ename[32];
  32. for (int i = 0; i < 20; i++) {
  33. sprintf(ename, i ? "eth%daddr" : "ethaddr", i);
  34. if (env_get(ename))
  35. env_set(ename, NULL);
  36. }
  37. }
  38. void octeontx2_board_get_mac_addr(u8 index, u8 *mac_addr)
  39. {
  40. u64 tmp_mac, board_mac_addr = fdt_get_board_mac_addr();
  41. static int board_mac_num;
  42. board_mac_num = fdt_get_board_mac_cnt();
  43. if ((!is_zero_ethaddr((u8 *)&board_mac_addr)) && board_mac_num) {
  44. tmp_mac = board_mac_addr;
  45. tmp_mac += index;
  46. tmp_mac = swab64(tmp_mac) >> 16;
  47. memcpy(mac_addr, (u8 *)&tmp_mac, ARP_HLEN);
  48. board_mac_num--;
  49. } else {
  50. memset(mac_addr, 0, ARP_HLEN);
  51. }
  52. debug("%s mac %pM\n", __func__, mac_addr);
  53. }
  54. void board_quiesce_devices(void)
  55. {
  56. struct uclass *uc_dev;
  57. int ret;
  58. /* Removes all RVU PF devices */
  59. ret = uclass_get(UCLASS_ETH, &uc_dev);
  60. if (uc_dev)
  61. ret = uclass_destroy(uc_dev);
  62. if (ret)
  63. printf("couldn't remove rvu pf devices\n");
  64. if (IS_ENABLED(CONFIG_OCTEONTX2_CGX_INTF)) {
  65. /* Bring down all cgx lmac links */
  66. cgx_intf_shutdown();
  67. }
  68. /* Removes all CGX and RVU AF devices */
  69. ret = uclass_get(UCLASS_MISC, &uc_dev);
  70. if (uc_dev)
  71. ret = uclass_destroy(uc_dev);
  72. if (ret)
  73. printf("couldn't remove misc (cgx/rvu_af) devices\n");
  74. /* SMC call - removes all LF<->PF mappings */
  75. smc_disable_rvu_lfs(0);
  76. }
  77. int board_early_init_r(void)
  78. {
  79. pci_init();
  80. return 0;
  81. }
  82. int board_init(void)
  83. {
  84. return 0;
  85. }
  86. int timer_init(void)
  87. {
  88. return 0;
  89. }
  90. int dram_init(void)
  91. {
  92. gd->ram_size = smc_dram_size(0);
  93. gd->ram_size -= CONFIG_SYS_SDRAM_BASE;
  94. mem_map_fill();
  95. return 0;
  96. }
  97. void board_late_probe_devices(void)
  98. {
  99. struct udevice *dev;
  100. int err, cgx_cnt = 3, i;
  101. /* Probe MAC(CGX) and NIC AF devices before Network stack init */
  102. for (i = 0; i < cgx_cnt; i++) {
  103. err = dm_pci_find_device(PCI_VENDOR_ID_CAVIUM,
  104. PCI_DEVICE_ID_CAVIUM_CGX, i, &dev);
  105. if (err)
  106. debug("%s CGX%d device not found\n", __func__, i);
  107. }
  108. err = dm_pci_find_device(PCI_VENDOR_ID_CAVIUM,
  109. PCI_DEVICE_ID_CAVIUM_RVU_AF, 0, &dev);
  110. if (err)
  111. debug("NIC AF device not found\n");
  112. }
  113. /**
  114. * Board late initialization routine.
  115. */
  116. int board_late_init(void)
  117. {
  118. char boardname[32];
  119. char boardserial[150], boardrev[150];
  120. long val;
  121. bool save_env = false;
  122. const char *str;
  123. debug("%s()\n", __func__);
  124. /*
  125. * Now that pci_init initializes env device.
  126. * Try to cleanup ethaddr env variables, this is needed
  127. * as with each boot, configuration of QLM can change.
  128. */
  129. cleanup_env_ethaddr();
  130. snprintf(boardname, sizeof(boardname), "%s> ", fdt_get_board_model());
  131. env_set("prompt", boardname);
  132. set_working_fdt_addr(env_get_hex("fdtcontroladdr", fdt_base_addr));
  133. str = fdt_get_board_revision();
  134. if (str) {
  135. snprintf(boardrev, sizeof(boardrev), "%s", str);
  136. if (env_get("boardrev") &&
  137. strcmp(boardrev, env_get("boardrev")))
  138. save_env = true;
  139. env_set("boardrev", boardrev);
  140. }
  141. str = fdt_get_board_serial();
  142. if (str) {
  143. snprintf(boardserial, sizeof(boardserial), "%s", str);
  144. if (env_get("serial#") &&
  145. strcmp(boardserial, env_get("serial#")))
  146. save_env = true;
  147. env_set("serial#", boardserial);
  148. }
  149. val = env_get_hex("disable_ooo", 0);
  150. smc_configure_ooo(val);
  151. if (IS_ENABLED(CONFIG_NET_OCTEONTX2))
  152. board_late_probe_devices();
  153. if (save_env)
  154. env_save();
  155. return 0;
  156. }
  157. /*
  158. * Invoked before relocation, so limit to stack variables.
  159. */
  160. int checkboard(void)
  161. {
  162. printf("Board: %s\n", fdt_get_board_model());
  163. return 0;
  164. }
  165. void board_acquire_flash_arb(bool acquire)
  166. {
  167. union cpc_boot_ownerx ownerx;
  168. if (!acquire) {
  169. ownerx.u = readl(CPC_BOOT_OWNERX(3));
  170. ownerx.s.boot_req = 0;
  171. writel(ownerx.u, CPC_BOOT_OWNERX(3));
  172. } else {
  173. ownerx.u = 0;
  174. ownerx.s.boot_req = 1;
  175. writel(ownerx.u, CPC_BOOT_OWNERX(3));
  176. udelay(1);
  177. do {
  178. ownerx.u = readl(CPC_BOOT_OWNERX(3));
  179. } while (ownerx.s.boot_wait);
  180. }
  181. }
  182. int last_stage_init(void)
  183. {
  184. (void)smc_flsf_fw_booted();
  185. return 0;
  186. }
  187. static int do_go_uboot(struct cmd_tbl *cmdtp, int flag, int argc,
  188. char *const argv[])
  189. {
  190. typedef void __noreturn (*uboot_entry_t)(ulong, void *);
  191. uboot_entry_t entry;
  192. ulong addr;
  193. void *fdt;
  194. if (argc < 2)
  195. return CMD_RET_USAGE;
  196. addr = hextoul(argv[1], NULL);
  197. fdt = board_fdt_blob_setup();
  198. entry = (uboot_entry_t)addr;
  199. flush_cache((ulong)addr, 1 << 20); /* 1MiB should be enough */
  200. dcache_disable();
  201. printf("## Starting U-Boot at %p (FDT at %p)...\n", entry, fdt);
  202. entry(0, fdt);
  203. return 0;
  204. }
  205. U_BOOT_CMD(go_uboot, 2, 0, do_go_uboot,
  206. "Start U-Boot from RAM (pass FDT via x1 register)",
  207. "");