mc.c 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370
  1. /*
  2. * Copyright (C) 2017 NXP Semiconductors
  3. * Copyright (C) 2014 Freescale Semiconductor
  4. *
  5. * SPDX-License-Identifier: GPL-2.0+
  6. */
  7. #include <common.h>
  8. #include <errno.h>
  9. #include <linux/bug.h>
  10. #include <asm/io.h>
  11. #include <libfdt.h>
  12. #include <net.h>
  13. #include <fdt_support.h>
  14. #include <fsl-mc/fsl_mc.h>
  15. #include <fsl-mc/fsl_mc_sys.h>
  16. #include <fsl-mc/fsl_mc_private.h>
  17. #include <fsl-mc/fsl_dpmng.h>
  18. #include <fsl-mc/fsl_dprc.h>
  19. #include <fsl-mc/fsl_dpio.h>
  20. #include <fsl-mc/fsl_dpni.h>
  21. #include <fsl-mc/fsl_qbman_portal.h>
  22. #include <fsl-mc/ldpaa_wriop.h>
  23. #define MC_RAM_BASE_ADDR_ALIGNMENT (512UL * 1024 * 1024)
  24. #define MC_RAM_BASE_ADDR_ALIGNMENT_MASK (~(MC_RAM_BASE_ADDR_ALIGNMENT - 1))
  25. #define MC_RAM_SIZE_ALIGNMENT (256UL * 1024 * 1024)
  26. #define MC_MEM_SIZE_ENV_VAR "mcmemsize"
  27. #define MC_BOOT_TIMEOUT_ENV_VAR "mcboottimeout"
  28. DECLARE_GLOBAL_DATA_PTR;
  29. static int mc_boot_status = -1;
  30. static int mc_dpl_applied = -1;
  31. #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET
  32. static int mc_aiop_applied = -1;
  33. #endif
  34. struct fsl_mc_io *root_mc_io = NULL;
  35. struct fsl_mc_io *dflt_mc_io = NULL; /* child container */
  36. uint16_t root_dprc_handle = 0;
  37. uint16_t dflt_dprc_handle = 0;
  38. int child_dprc_id;
  39. struct fsl_dpbp_obj *dflt_dpbp = NULL;
  40. struct fsl_dpio_obj *dflt_dpio = NULL;
  41. struct fsl_dpni_obj *dflt_dpni = NULL;
  42. static u64 mc_lazy_dpl_addr;
  43. #ifdef DEBUG
  44. void dump_ram_words(const char *title, void *addr)
  45. {
  46. int i;
  47. uint32_t *words = addr;
  48. printf("Dumping beginning of %s (%p):\n", title, addr);
  49. for (i = 0; i < 16; i++)
  50. printf("%#x ", words[i]);
  51. printf("\n");
  52. }
  53. void dump_mc_ccsr_regs(struct mc_ccsr_registers __iomem *mc_ccsr_regs)
  54. {
  55. printf("MC CCSR registers:\n"
  56. "reg_gcr1 %#x\n"
  57. "reg_gsr %#x\n"
  58. "reg_sicbalr %#x\n"
  59. "reg_sicbahr %#x\n"
  60. "reg_sicapr %#x\n"
  61. "reg_mcfbalr %#x\n"
  62. "reg_mcfbahr %#x\n"
  63. "reg_mcfapr %#x\n"
  64. "reg_psr %#x\n",
  65. mc_ccsr_regs->reg_gcr1,
  66. mc_ccsr_regs->reg_gsr,
  67. mc_ccsr_regs->reg_sicbalr,
  68. mc_ccsr_regs->reg_sicbahr,
  69. mc_ccsr_regs->reg_sicapr,
  70. mc_ccsr_regs->reg_mcfbalr,
  71. mc_ccsr_regs->reg_mcfbahr,
  72. mc_ccsr_regs->reg_mcfapr,
  73. mc_ccsr_regs->reg_psr);
  74. }
  75. #else
  76. #define dump_ram_words(title, addr)
  77. #define dump_mc_ccsr_regs(mc_ccsr_regs)
  78. #endif /* DEBUG */
  79. #ifndef CONFIG_SYS_LS_MC_FW_IN_DDR
  80. /**
  81. * Copying MC firmware or DPL image to DDR
  82. */
  83. static int mc_copy_image(const char *title,
  84. u64 image_addr, u32 image_size, u64 mc_ram_addr)
  85. {
  86. debug("%s copied to address %p\n", title, (void *)mc_ram_addr);
  87. memcpy((void *)mc_ram_addr, (void *)image_addr, image_size);
  88. flush_dcache_range(mc_ram_addr, mc_ram_addr + image_size);
  89. return 0;
  90. }
  91. /**
  92. * MC firmware FIT image parser checks if the image is in FIT
  93. * format, verifies integrity of the image and calculates
  94. * raw image address and size values.
  95. * Returns 0 on success and a negative errno on error.
  96. * task fail.
  97. **/
  98. int parse_mc_firmware_fit_image(u64 mc_fw_addr,
  99. const void **raw_image_addr,
  100. size_t *raw_image_size)
  101. {
  102. int format;
  103. void *fit_hdr;
  104. int node_offset;
  105. const void *data;
  106. size_t size;
  107. const char *uname = "firmware";
  108. fit_hdr = (void *)mc_fw_addr;
  109. /* Check if Image is in FIT format */
  110. format = genimg_get_format(fit_hdr);
  111. if (format != IMAGE_FORMAT_FIT) {
  112. printf("fsl-mc: ERR: Bad firmware image (not a FIT image)\n");
  113. return -EINVAL;
  114. }
  115. if (!fit_check_format(fit_hdr)) {
  116. printf("fsl-mc: ERR: Bad firmware image (bad FIT header)\n");
  117. return -EINVAL;
  118. }
  119. node_offset = fit_image_get_node(fit_hdr, uname);
  120. if (node_offset < 0) {
  121. printf("fsl-mc: ERR: Bad firmware image (missing subimage)\n");
  122. return -ENOENT;
  123. }
  124. /* Verify MC firmware image */
  125. if (!(fit_image_verify(fit_hdr, node_offset))) {
  126. printf("fsl-mc: ERR: Bad firmware image (bad CRC)\n");
  127. return -EINVAL;
  128. }
  129. /* Get address and size of raw image */
  130. fit_image_get_data(fit_hdr, node_offset, &data, &size);
  131. *raw_image_addr = data;
  132. *raw_image_size = size;
  133. return 0;
  134. }
  135. #endif
  136. static int mc_fixup_dpc_mac_addr(void *blob, int noff, int dpmac_id,
  137. struct eth_device *eth_dev)
  138. {
  139. int nodeoffset, err = 0;
  140. char mac_name[10];
  141. const char link_type_mode[] = "FIXED_LINK";
  142. unsigned char env_enetaddr[6];
  143. sprintf(mac_name, "mac@%d", dpmac_id);
  144. /* node not found - create it */
  145. nodeoffset = fdt_subnode_offset(blob, noff, (const char *) mac_name);
  146. if (nodeoffset < 0) {
  147. err = fdt_increase_size(blob, 200);
  148. if (err) {
  149. printf("fdt_increase_size: err=%s\n",
  150. fdt_strerror(err));
  151. return err;
  152. }
  153. nodeoffset = fdt_add_subnode(blob, noff, mac_name);
  154. /* add default property of fixed link */
  155. err = fdt_appendprop_string(blob, nodeoffset,
  156. "link_type", link_type_mode);
  157. if (err) {
  158. printf("fdt_appendprop_string: err=%s\n",
  159. fdt_strerror(err));
  160. return err;
  161. }
  162. }
  163. /* port_mac_address property present in DPC */
  164. if (fdt_get_property(blob, nodeoffset, "port_mac_address", NULL)) {
  165. /* MAC addr randomly assigned - leave the one in DPC */
  166. eth_getenv_enetaddr_by_index("eth", eth_dev->index,
  167. env_enetaddr);
  168. if (is_zero_ethaddr(env_enetaddr))
  169. return err;
  170. /* replace DPC MAC address with u-boot env one */
  171. err = fdt_setprop(blob, nodeoffset, "port_mac_address",
  172. eth_dev->enetaddr, 6);
  173. if (err) {
  174. printf("fdt_setprop mac: err=%s\n", fdt_strerror(err));
  175. return err;
  176. }
  177. return 0;
  178. }
  179. /* append port_mac_address property to mac node in DPC */
  180. err = fdt_increase_size(blob, 80);
  181. if (err) {
  182. printf("fdt_increase_size: err=%s\n", fdt_strerror(err));
  183. return err;
  184. }
  185. err = fdt_appendprop(blob, nodeoffset,
  186. "port_mac_address", eth_dev->enetaddr, 6);
  187. if (err) {
  188. printf("fdt_appendprop: err=%s\n", fdt_strerror(err));
  189. return err;
  190. }
  191. return err;
  192. }
  193. static int mc_fixup_dpc(u64 dpc_addr)
  194. {
  195. void *blob = (void *)dpc_addr;
  196. int nodeoffset, err = 0;
  197. char ethname[10];
  198. struct eth_device *eth_dev;
  199. int i;
  200. /* delete any existing ICID pools */
  201. nodeoffset = fdt_path_offset(blob, "/resources/icid_pools");
  202. if (fdt_del_node(blob, nodeoffset) < 0)
  203. printf("\nfsl-mc: WARNING: could not delete ICID pool\n");
  204. /* add a new pool */
  205. nodeoffset = fdt_path_offset(blob, "/resources");
  206. if (nodeoffset < 0) {
  207. printf("\nfsl-mc: ERROR: DPC is missing /resources\n");
  208. return -EINVAL;
  209. }
  210. nodeoffset = fdt_add_subnode(blob, nodeoffset, "icid_pools");
  211. nodeoffset = fdt_add_subnode(blob, nodeoffset, "icid_pool@0");
  212. do_fixup_by_path_u32(blob, "/resources/icid_pools/icid_pool@0",
  213. "base_icid", FSL_DPAA2_STREAM_ID_START, 1);
  214. do_fixup_by_path_u32(blob, "/resources/icid_pools/icid_pool@0",
  215. "num",
  216. FSL_DPAA2_STREAM_ID_END -
  217. FSL_DPAA2_STREAM_ID_START + 1, 1);
  218. /* fixup MAC addresses for dpmac ports */
  219. nodeoffset = fdt_path_offset(blob, "/board_info/ports");
  220. if (nodeoffset < 0)
  221. goto out;
  222. for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) {
  223. /* port not enabled */
  224. if ((wriop_is_enabled_dpmac(i) != 1) ||
  225. (wriop_get_phy_address(i) == -1))
  226. continue;
  227. sprintf(ethname, "DPMAC%d@%s", i,
  228. phy_interface_strings[wriop_get_enet_if(i)]);
  229. eth_dev = eth_get_dev_by_name(ethname);
  230. if (eth_dev == NULL)
  231. continue;
  232. err = mc_fixup_dpc_mac_addr(blob, nodeoffset, i, eth_dev);
  233. if (err) {
  234. printf("mc_fixup_dpc_mac_addr failed: err=%s\n",
  235. fdt_strerror(err));
  236. goto out;
  237. }
  238. }
  239. out:
  240. flush_dcache_range(dpc_addr, dpc_addr + fdt_totalsize(blob));
  241. return err;
  242. }
  243. static int load_mc_dpc(u64 mc_ram_addr, size_t mc_ram_size, u64 mc_dpc_addr)
  244. {
  245. u64 mc_dpc_offset;
  246. #ifndef CONFIG_SYS_LS_MC_DPC_IN_DDR
  247. int error;
  248. void *dpc_fdt_hdr;
  249. int dpc_size;
  250. #endif
  251. #ifdef CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET
  252. BUILD_BUG_ON((CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET & 0x3) != 0 ||
  253. CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET > 0xffffffff);
  254. mc_dpc_offset = CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET;
  255. #else
  256. #error "CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET not defined"
  257. #endif
  258. /*
  259. * Load the MC DPC blob in the MC private DRAM block:
  260. */
  261. #ifdef CONFIG_SYS_LS_MC_DPC_IN_DDR
  262. printf("MC DPC is preloaded to %#llx\n", mc_ram_addr + mc_dpc_offset);
  263. #else
  264. /*
  265. * Get address and size of the DPC blob stored in flash:
  266. */
  267. dpc_fdt_hdr = (void *)mc_dpc_addr;
  268. error = fdt_check_header(dpc_fdt_hdr);
  269. if (error != 0) {
  270. /*
  271. * Don't return with error here, since the MC firmware can
  272. * still boot without a DPC
  273. */
  274. printf("\nfsl-mc: WARNING: No DPC image found");
  275. return 0;
  276. }
  277. dpc_size = fdt_totalsize(dpc_fdt_hdr);
  278. if (dpc_size > CONFIG_SYS_LS_MC_DPC_MAX_LENGTH) {
  279. printf("\nfsl-mc: ERROR: Bad DPC image (too large: %d)\n",
  280. dpc_size);
  281. return -EINVAL;
  282. }
  283. mc_copy_image("MC DPC blob",
  284. (u64)dpc_fdt_hdr, dpc_size, mc_ram_addr + mc_dpc_offset);
  285. #endif /* not defined CONFIG_SYS_LS_MC_DPC_IN_DDR */
  286. if (mc_fixup_dpc(mc_ram_addr + mc_dpc_offset))
  287. return -EINVAL;
  288. dump_ram_words("DPC", (void *)(mc_ram_addr + mc_dpc_offset));
  289. return 0;
  290. }
  291. static int load_mc_dpl(u64 mc_ram_addr, size_t mc_ram_size, u64 mc_dpl_addr)
  292. {
  293. u64 mc_dpl_offset;
  294. #ifndef CONFIG_SYS_LS_MC_DPL_IN_DDR
  295. int error;
  296. void *dpl_fdt_hdr;
  297. int dpl_size;
  298. #endif
  299. #ifdef CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET
  300. BUILD_BUG_ON((CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET & 0x3) != 0 ||
  301. CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET > 0xffffffff);
  302. mc_dpl_offset = CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET;
  303. #else
  304. #error "CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET not defined"
  305. #endif
  306. /*
  307. * Load the MC DPL blob in the MC private DRAM block:
  308. */
  309. #ifdef CONFIG_SYS_LS_MC_DPL_IN_DDR
  310. printf("MC DPL is preloaded to %#llx\n", mc_ram_addr + mc_dpl_offset);
  311. #else
  312. /*
  313. * Get address and size of the DPL blob stored in flash:
  314. */
  315. dpl_fdt_hdr = (void *)mc_dpl_addr;
  316. error = fdt_check_header(dpl_fdt_hdr);
  317. if (error != 0) {
  318. printf("\nfsl-mc: ERROR: Bad DPL image (bad header)\n");
  319. return error;
  320. }
  321. dpl_size = fdt_totalsize(dpl_fdt_hdr);
  322. if (dpl_size > CONFIG_SYS_LS_MC_DPL_MAX_LENGTH) {
  323. printf("\nfsl-mc: ERROR: Bad DPL image (too large: %d)\n",
  324. dpl_size);
  325. return -EINVAL;
  326. }
  327. mc_copy_image("MC DPL blob",
  328. (u64)dpl_fdt_hdr, dpl_size, mc_ram_addr + mc_dpl_offset);
  329. #endif /* not defined CONFIG_SYS_LS_MC_DPL_IN_DDR */
  330. dump_ram_words("DPL", (void *)(mc_ram_addr + mc_dpl_offset));
  331. return 0;
  332. }
  333. /**
  334. * Return the MC boot timeout value in milliseconds
  335. */
  336. static unsigned long get_mc_boot_timeout_ms(void)
  337. {
  338. unsigned long timeout_ms = CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS;
  339. char *timeout_ms_env_var = getenv(MC_BOOT_TIMEOUT_ENV_VAR);
  340. if (timeout_ms_env_var) {
  341. timeout_ms = simple_strtoul(timeout_ms_env_var, NULL, 10);
  342. if (timeout_ms == 0) {
  343. printf("fsl-mc: WARNING: Invalid value for \'"
  344. MC_BOOT_TIMEOUT_ENV_VAR
  345. "\' environment variable: %lu\n",
  346. timeout_ms);
  347. timeout_ms = CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS;
  348. }
  349. }
  350. return timeout_ms;
  351. }
  352. #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET
  353. __weak bool soc_has_aiop(void)
  354. {
  355. return false;
  356. }
  357. static int load_mc_aiop_img(u64 aiop_fw_addr)
  358. {
  359. u64 mc_ram_addr = mc_get_dram_addr();
  360. #ifndef CONFIG_SYS_LS_MC_DPC_IN_DDR
  361. void *aiop_img;
  362. #endif
  363. /* Check if AIOP is available */
  364. if (!soc_has_aiop())
  365. return -ENODEV;
  366. /*
  367. * Load the MC AIOP image in the MC private DRAM block:
  368. */
  369. #ifdef CONFIG_SYS_LS_MC_DPC_IN_DDR
  370. printf("MC AIOP is preloaded to %#llx\n", mc_ram_addr +
  371. CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET);
  372. #else
  373. aiop_img = (void *)aiop_fw_addr;
  374. mc_copy_image("MC AIOP image",
  375. (u64)aiop_img, CONFIG_SYS_LS_MC_AIOP_IMG_MAX_LENGTH,
  376. mc_ram_addr + CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET);
  377. #endif
  378. mc_aiop_applied = 0;
  379. return 0;
  380. }
  381. #endif
  382. static int wait_for_mc(bool booting_mc, u32 *final_reg_gsr)
  383. {
  384. u32 reg_gsr;
  385. u32 mc_fw_boot_status;
  386. unsigned long timeout_ms = get_mc_boot_timeout_ms();
  387. struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR;
  388. dmb();
  389. assert(timeout_ms > 0);
  390. for (;;) {
  391. udelay(1000); /* throttle polling */
  392. reg_gsr = in_le32(&mc_ccsr_regs->reg_gsr);
  393. mc_fw_boot_status = (reg_gsr & GSR_FS_MASK);
  394. if (mc_fw_boot_status & 0x1)
  395. break;
  396. timeout_ms--;
  397. if (timeout_ms == 0)
  398. break;
  399. }
  400. if (timeout_ms == 0) {
  401. printf("ERROR: timeout\n");
  402. /* TODO: Get an error status from an MC CCSR register */
  403. return -ETIMEDOUT;
  404. }
  405. if (mc_fw_boot_status != 0x1) {
  406. /*
  407. * TODO: Identify critical errors from the GSR register's FS
  408. * field and for those errors, set error to -ENODEV or other
  409. * appropriate errno, so that the status property is set to
  410. * failure in the fsl,dprc device tree node.
  411. */
  412. printf("WARNING: Firmware returned an error (GSR: %#x)\n",
  413. reg_gsr);
  414. } else {
  415. printf("SUCCESS\n");
  416. }
  417. *final_reg_gsr = reg_gsr;
  418. return 0;
  419. }
  420. int mc_init(u64 mc_fw_addr, u64 mc_dpc_addr)
  421. {
  422. int error = 0;
  423. int portal_id = 0;
  424. struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR;
  425. u64 mc_ram_addr = mc_get_dram_addr();
  426. u32 reg_gsr;
  427. u32 reg_mcfbalr;
  428. #ifndef CONFIG_SYS_LS_MC_FW_IN_DDR
  429. const void *raw_image_addr;
  430. size_t raw_image_size = 0;
  431. #endif
  432. struct mc_version mc_ver_info;
  433. u8 mc_ram_num_256mb_blocks;
  434. size_t mc_ram_size = mc_get_dram_block_size();
  435. mc_ram_num_256mb_blocks = mc_ram_size / MC_RAM_SIZE_ALIGNMENT;
  436. if (mc_ram_num_256mb_blocks < 1 || mc_ram_num_256mb_blocks > 0xff) {
  437. error = -EINVAL;
  438. printf("fsl-mc: ERROR: invalid MC private RAM size (%lu)\n",
  439. mc_ram_size);
  440. goto out;
  441. }
  442. /*
  443. * Management Complex cores should be held at reset out of POR.
  444. * U-Boot should be the first software to touch MC. To be safe,
  445. * we reset all cores again by setting GCR1 to 0. It doesn't do
  446. * anything if they are held at reset. After we setup the firmware
  447. * we kick off MC by deasserting the reset bit for core 0, and
  448. * deasserting the reset bits for Command Portal Managers.
  449. * The stop bits are not touched here. They are used to stop the
  450. * cores when they are active. Setting stop bits doesn't stop the
  451. * cores from fetching instructions when they are released from
  452. * reset.
  453. */
  454. out_le32(&mc_ccsr_regs->reg_gcr1, 0);
  455. dmb();
  456. #ifdef CONFIG_SYS_LS_MC_FW_IN_DDR
  457. printf("MC firmware is preloaded to %#llx\n", mc_ram_addr);
  458. #else
  459. error = parse_mc_firmware_fit_image(mc_fw_addr, &raw_image_addr,
  460. &raw_image_size);
  461. if (error != 0)
  462. goto out;
  463. /*
  464. * Load the MC FW at the beginning of the MC private DRAM block:
  465. */
  466. mc_copy_image("MC Firmware",
  467. (u64)raw_image_addr, raw_image_size, mc_ram_addr);
  468. #endif
  469. dump_ram_words("firmware", (void *)mc_ram_addr);
  470. error = load_mc_dpc(mc_ram_addr, mc_ram_size, mc_dpc_addr);
  471. if (error != 0)
  472. goto out;
  473. debug("mc_ccsr_regs %p\n", mc_ccsr_regs);
  474. dump_mc_ccsr_regs(mc_ccsr_regs);
  475. /*
  476. * Tell MC what is the address range of the DRAM block assigned to it:
  477. */
  478. reg_mcfbalr = (u32)mc_ram_addr |
  479. (mc_ram_num_256mb_blocks - 1);
  480. out_le32(&mc_ccsr_regs->reg_mcfbalr, reg_mcfbalr);
  481. out_le32(&mc_ccsr_regs->reg_mcfbahr,
  482. (u32)(mc_ram_addr >> 32));
  483. out_le32(&mc_ccsr_regs->reg_mcfapr, FSL_BYPASS_AMQ);
  484. /*
  485. * Tell the MC that we want delayed DPL deployment.
  486. */
  487. out_le32(&mc_ccsr_regs->reg_gsr, 0xDD00);
  488. printf("\nfsl-mc: Booting Management Complex ... ");
  489. /*
  490. * Deassert reset and release MC core 0 to run
  491. */
  492. out_le32(&mc_ccsr_regs->reg_gcr1, GCR1_P1_DE_RST | GCR1_M_ALL_DE_RST);
  493. error = wait_for_mc(true, &reg_gsr);
  494. if (error != 0)
  495. goto out;
  496. /*
  497. * TODO: need to obtain the portal_id for the root container from the
  498. * DPL
  499. */
  500. portal_id = 0;
  501. /*
  502. * Initialize the global default MC portal
  503. * And check that the MC firmware is responding portal commands:
  504. */
  505. root_mc_io = (struct fsl_mc_io *)malloc(sizeof(struct fsl_mc_io));
  506. if (!root_mc_io) {
  507. printf(" No memory: malloc() failed\n");
  508. return -ENOMEM;
  509. }
  510. root_mc_io->mmio_regs = SOC_MC_PORTAL_ADDR(portal_id);
  511. debug("Checking access to MC portal of root DPRC container (portal_id %d, portal physical addr %p)\n",
  512. portal_id, root_mc_io->mmio_regs);
  513. error = mc_get_version(root_mc_io, MC_CMD_NO_FLAGS, &mc_ver_info);
  514. if (error != 0) {
  515. printf("fsl-mc: ERROR: Firmware version check failed (error: %d)\n",
  516. error);
  517. goto out;
  518. }
  519. printf("fsl-mc: Management Complex booted (version: %d.%d.%d, boot status: %#x)\n",
  520. mc_ver_info.major, mc_ver_info.minor, mc_ver_info.revision,
  521. reg_gsr & GSR_FS_MASK);
  522. out:
  523. if (error != 0)
  524. mc_boot_status = error;
  525. else
  526. mc_boot_status = 0;
  527. return error;
  528. }
  529. int mc_apply_dpl(u64 mc_dpl_addr)
  530. {
  531. struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR;
  532. int error = 0;
  533. u32 reg_gsr;
  534. u64 mc_ram_addr = mc_get_dram_addr();
  535. size_t mc_ram_size = mc_get_dram_block_size();
  536. if (!mc_dpl_addr)
  537. return -1;
  538. error = load_mc_dpl(mc_ram_addr, mc_ram_size, mc_dpl_addr);
  539. if (error != 0)
  540. return error;
  541. /*
  542. * Tell the MC to deploy the DPL:
  543. */
  544. out_le32(&mc_ccsr_regs->reg_gsr, 0x0);
  545. printf("fsl-mc: Deploying data path layout ... ");
  546. error = wait_for_mc(false, &reg_gsr);
  547. if (!error)
  548. mc_dpl_applied = 0;
  549. return error;
  550. }
  551. int get_mc_boot_status(void)
  552. {
  553. return mc_boot_status;
  554. }
  555. #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET
  556. int get_aiop_apply_status(void)
  557. {
  558. return mc_aiop_applied;
  559. }
  560. #endif
  561. int get_dpl_apply_status(void)
  562. {
  563. return mc_dpl_applied;
  564. }
  565. /**
  566. * Return the MC address of private DRAM block.
  567. */
  568. u64 mc_get_dram_addr(void)
  569. {
  570. return gd->arch.resv_ram;
  571. }
  572. /**
  573. * Return the actual size of the MC private DRAM block.
  574. */
  575. unsigned long mc_get_dram_block_size(void)
  576. {
  577. unsigned long dram_block_size = CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE;
  578. char *dram_block_size_env_var = getenv(MC_MEM_SIZE_ENV_VAR);
  579. if (dram_block_size_env_var) {
  580. dram_block_size = simple_strtoul(dram_block_size_env_var, NULL,
  581. 10);
  582. if (dram_block_size < CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE) {
  583. printf("fsl-mc: WARNING: Invalid value for \'"
  584. MC_MEM_SIZE_ENV_VAR
  585. "\' environment variable: %lu\n",
  586. dram_block_size);
  587. dram_block_size = CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE;
  588. }
  589. }
  590. return dram_block_size;
  591. }
  592. int fsl_mc_ldpaa_init(bd_t *bis)
  593. {
  594. int i;
  595. for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++)
  596. if ((wriop_is_enabled_dpmac(i) == 1) &&
  597. (wriop_get_phy_address(i) != -1))
  598. ldpaa_eth_init(i, wriop_get_enet_if(i));
  599. return 0;
  600. }
  601. static int dprc_version_check(struct fsl_mc_io *mc_io, uint16_t handle)
  602. {
  603. struct dprc_attributes attr;
  604. int error;
  605. memset(&attr, 0, sizeof(struct dprc_attributes));
  606. error = dprc_get_attributes(mc_io, MC_CMD_NO_FLAGS, handle, &attr);
  607. if (error == 0) {
  608. if ((attr.version.major != DPRC_VER_MAJOR) ||
  609. (attr.version.minor != DPRC_VER_MINOR)) {
  610. printf("DPRC version mismatch found %u.%u,",
  611. attr.version.major,
  612. attr.version.minor);
  613. printf("supported version is %u.%u\n",
  614. DPRC_VER_MAJOR, DPRC_VER_MINOR);
  615. }
  616. }
  617. return error;
  618. }
  619. static int dpio_init(void)
  620. {
  621. struct qbman_swp_desc p_des;
  622. struct dpio_attr attr;
  623. struct dpio_cfg dpio_cfg;
  624. int err = 0;
  625. dflt_dpio = (struct fsl_dpio_obj *)malloc(sizeof(struct fsl_dpio_obj));
  626. if (!dflt_dpio) {
  627. printf("No memory: malloc() failed\n");
  628. err = -ENOMEM;
  629. goto err_malloc;
  630. }
  631. dpio_cfg.channel_mode = DPIO_LOCAL_CHANNEL;
  632. dpio_cfg.num_priorities = 8;
  633. err = dpio_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpio_cfg,
  634. &dflt_dpio->dpio_handle);
  635. if (err < 0) {
  636. printf("dpio_create() failed: %d\n", err);
  637. err = -ENODEV;
  638. goto err_create;
  639. }
  640. memset(&attr, 0, sizeof(struct dpio_attr));
  641. err = dpio_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS,
  642. dflt_dpio->dpio_handle, &attr);
  643. if (err < 0) {
  644. printf("dpio_get_attributes() failed: %d\n", err);
  645. goto err_get_attr;
  646. }
  647. if ((attr.version.major != DPIO_VER_MAJOR) ||
  648. (attr.version.minor != DPIO_VER_MINOR)) {
  649. printf("DPIO version mismatch found %u.%u,",
  650. attr.version.major, attr.version.minor);
  651. printf("supported version is %u.%u\n",
  652. DPIO_VER_MAJOR, DPIO_VER_MINOR);
  653. }
  654. dflt_dpio->dpio_id = attr.id;
  655. #ifdef DEBUG
  656. printf("Init: DPIO id=0x%d\n", dflt_dpio->dpio_id);
  657. #endif
  658. err = dpio_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle);
  659. if (err < 0) {
  660. printf("dpio_enable() failed %d\n", err);
  661. goto err_get_enable;
  662. }
  663. debug("ce_offset=0x%llx, ci_offset=0x%llx, portalid=%d, prios=%d\n",
  664. attr.qbman_portal_ce_offset,
  665. attr.qbman_portal_ci_offset,
  666. attr.qbman_portal_id,
  667. attr.num_priorities);
  668. p_des.cena_bar = (void *)(SOC_QBMAN_PORTALS_BASE_ADDR
  669. + attr.qbman_portal_ce_offset);
  670. p_des.cinh_bar = (void *)(SOC_QBMAN_PORTALS_BASE_ADDR
  671. + attr.qbman_portal_ci_offset);
  672. dflt_dpio->sw_portal = qbman_swp_init(&p_des);
  673. if (dflt_dpio->sw_portal == NULL) {
  674. printf("qbman_swp_init() failed\n");
  675. goto err_get_swp_init;
  676. }
  677. return 0;
  678. err_get_swp_init:
  679. dpio_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle);
  680. err_get_enable:
  681. err_get_attr:
  682. dpio_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle);
  683. dpio_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle);
  684. err_create:
  685. free(dflt_dpio);
  686. err_malloc:
  687. return err;
  688. }
  689. static int dpio_exit(void)
  690. {
  691. int err;
  692. err = dpio_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle);
  693. if (err < 0) {
  694. printf("dpio_disable() failed: %d\n", err);
  695. goto err;
  696. }
  697. err = dpio_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle);
  698. if (err < 0) {
  699. printf("dpio_destroy() failed: %d\n", err);
  700. goto err;
  701. }
  702. #ifdef DEBUG
  703. printf("Exit: DPIO id=0x%d\n", dflt_dpio->dpio_id);
  704. #endif
  705. if (dflt_dpio)
  706. free(dflt_dpio);
  707. return 0;
  708. err:
  709. return err;
  710. }
  711. static int dprc_init(void)
  712. {
  713. int err, child_portal_id, container_id;
  714. struct dprc_cfg cfg;
  715. uint64_t mc_portal_offset;
  716. /* Open root container */
  717. err = dprc_get_container_id(root_mc_io, MC_CMD_NO_FLAGS, &container_id);
  718. if (err < 0) {
  719. printf("dprc_get_container_id(): Root failed: %d\n", err);
  720. goto err_root_container_id;
  721. }
  722. #ifdef DEBUG
  723. printf("Root container id = %d\n", container_id);
  724. #endif
  725. err = dprc_open(root_mc_io, MC_CMD_NO_FLAGS, container_id,
  726. &root_dprc_handle);
  727. if (err < 0) {
  728. printf("dprc_open(): Root Container failed: %d\n", err);
  729. goto err_root_open;
  730. }
  731. if (!root_dprc_handle) {
  732. printf("dprc_open(): Root Container Handle is not valid\n");
  733. goto err_root_open;
  734. }
  735. err = dprc_version_check(root_mc_io, root_dprc_handle);
  736. if (err < 0) {
  737. printf("dprc_version_check() failed: %d\n", err);
  738. goto err_root_open;
  739. }
  740. memset(&cfg, 0, sizeof(struct dprc_cfg));
  741. cfg.options = DPRC_CFG_OPT_TOPOLOGY_CHANGES_ALLOWED |
  742. DPRC_CFG_OPT_OBJ_CREATE_ALLOWED |
  743. DPRC_CFG_OPT_ALLOC_ALLOWED;
  744. cfg.icid = DPRC_GET_ICID_FROM_POOL;
  745. cfg.portal_id = DPRC_GET_PORTAL_ID_FROM_POOL;
  746. err = dprc_create_container(root_mc_io, MC_CMD_NO_FLAGS,
  747. root_dprc_handle,
  748. &cfg,
  749. &child_dprc_id,
  750. &mc_portal_offset);
  751. if (err < 0) {
  752. printf("dprc_create_container() failed: %d\n", err);
  753. goto err_create;
  754. }
  755. dflt_mc_io = (struct fsl_mc_io *)malloc(sizeof(struct fsl_mc_io));
  756. if (!dflt_mc_io) {
  757. err = -ENOMEM;
  758. printf(" No memory: malloc() failed\n");
  759. goto err_malloc;
  760. }
  761. child_portal_id = MC_PORTAL_OFFSET_TO_PORTAL_ID(mc_portal_offset);
  762. dflt_mc_io->mmio_regs = SOC_MC_PORTAL_ADDR(child_portal_id);
  763. #ifdef DEBUG
  764. printf("MC portal of child DPRC container: %d, physical addr %p)\n",
  765. child_dprc_id, dflt_mc_io->mmio_regs);
  766. #endif
  767. err = dprc_open(dflt_mc_io, MC_CMD_NO_FLAGS, child_dprc_id,
  768. &dflt_dprc_handle);
  769. if (err < 0) {
  770. printf("dprc_open(): Child container failed: %d\n", err);
  771. goto err_child_open;
  772. }
  773. if (!dflt_dprc_handle) {
  774. printf("dprc_open(): Child container Handle is not valid\n");
  775. goto err_child_open;
  776. }
  777. return 0;
  778. err_child_open:
  779. free(dflt_mc_io);
  780. err_malloc:
  781. dprc_destroy_container(root_mc_io, MC_CMD_NO_FLAGS,
  782. root_dprc_handle, child_dprc_id);
  783. err_create:
  784. dprc_close(root_mc_io, MC_CMD_NO_FLAGS, root_dprc_handle);
  785. err_root_open:
  786. err_root_container_id:
  787. return err;
  788. }
  789. static int dprc_exit(void)
  790. {
  791. int err;
  792. err = dprc_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dprc_handle);
  793. if (err < 0) {
  794. printf("dprc_close(): Child failed: %d\n", err);
  795. goto err;
  796. }
  797. err = dprc_destroy_container(root_mc_io, MC_CMD_NO_FLAGS,
  798. root_dprc_handle, child_dprc_id);
  799. if (err < 0) {
  800. printf("dprc_destroy_container() failed: %d\n", err);
  801. goto err;
  802. }
  803. err = dprc_close(root_mc_io, MC_CMD_NO_FLAGS, root_dprc_handle);
  804. if (err < 0) {
  805. printf("dprc_close(): Root failed: %d\n", err);
  806. goto err;
  807. }
  808. if (dflt_mc_io)
  809. free(dflt_mc_io);
  810. if (root_mc_io)
  811. free(root_mc_io);
  812. return 0;
  813. err:
  814. return err;
  815. }
  816. static int dpbp_init(void)
  817. {
  818. int err;
  819. struct dpbp_attr dpbp_attr;
  820. struct dpbp_cfg dpbp_cfg;
  821. dflt_dpbp = (struct fsl_dpbp_obj *)malloc(sizeof(struct fsl_dpbp_obj));
  822. if (!dflt_dpbp) {
  823. printf("No memory: malloc() failed\n");
  824. err = -ENOMEM;
  825. goto err_malloc;
  826. }
  827. dpbp_cfg.options = 512;
  828. err = dpbp_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpbp_cfg,
  829. &dflt_dpbp->dpbp_handle);
  830. if (err < 0) {
  831. err = -ENODEV;
  832. printf("dpbp_create() failed: %d\n", err);
  833. goto err_create;
  834. }
  835. memset(&dpbp_attr, 0, sizeof(struct dpbp_attr));
  836. err = dpbp_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS,
  837. dflt_dpbp->dpbp_handle,
  838. &dpbp_attr);
  839. if (err < 0) {
  840. printf("dpbp_get_attributes() failed: %d\n", err);
  841. goto err_get_attr;
  842. }
  843. if ((dpbp_attr.version.major != DPBP_VER_MAJOR) ||
  844. (dpbp_attr.version.minor != DPBP_VER_MINOR)) {
  845. printf("DPBP version mismatch found %u.%u,",
  846. dpbp_attr.version.major, dpbp_attr.version.minor);
  847. printf("supported version is %u.%u\n",
  848. DPBP_VER_MAJOR, DPBP_VER_MINOR);
  849. }
  850. dflt_dpbp->dpbp_attr.id = dpbp_attr.id;
  851. #ifdef DEBUG
  852. printf("Init: DPBP id=0x%d\n", dflt_dpbp->dpbp_attr.id);
  853. #endif
  854. err = dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
  855. if (err < 0) {
  856. printf("dpbp_close() failed: %d\n", err);
  857. goto err_close;
  858. }
  859. return 0;
  860. err_close:
  861. free(dflt_dpbp);
  862. err_get_attr:
  863. dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
  864. dpbp_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
  865. err_create:
  866. err_malloc:
  867. return err;
  868. }
  869. static int dpbp_exit(void)
  870. {
  871. int err;
  872. err = dpbp_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_attr.id,
  873. &dflt_dpbp->dpbp_handle);
  874. if (err < 0) {
  875. printf("dpbp_open() failed: %d\n", err);
  876. goto err;
  877. }
  878. err = dpbp_destroy(dflt_mc_io, MC_CMD_NO_FLAGS,
  879. dflt_dpbp->dpbp_handle);
  880. if (err < 0) {
  881. printf("dpbp_destroy() failed: %d\n", err);
  882. goto err;
  883. }
  884. #ifdef DEBUG
  885. printf("Exit: DPBP id=0x%d\n", dflt_dpbp->dpbp_attr.id);
  886. #endif
  887. if (dflt_dpbp)
  888. free(dflt_dpbp);
  889. return 0;
  890. err:
  891. return err;
  892. }
  893. static int dpni_init(void)
  894. {
  895. int err;
  896. struct dpni_attr dpni_attr;
  897. uint8_t ext_cfg_buf[256] = {0};
  898. struct dpni_extended_cfg dpni_extended_cfg;
  899. struct dpni_cfg dpni_cfg;
  900. dflt_dpni = (struct fsl_dpni_obj *)malloc(sizeof(struct fsl_dpni_obj));
  901. if (!dflt_dpni) {
  902. printf("No memory: malloc() failed\n");
  903. err = -ENOMEM;
  904. goto err_malloc;
  905. }
  906. memset(&dpni_extended_cfg, 0, sizeof(dpni_extended_cfg));
  907. err = dpni_prepare_extended_cfg(&dpni_extended_cfg, &ext_cfg_buf[0]);
  908. if (err < 0) {
  909. err = -ENODEV;
  910. printf("dpni_prepare_extended_cfg() failed: %d\n", err);
  911. goto err_prepare_extended_cfg;
  912. }
  913. memset(&dpni_cfg, 0, sizeof(dpni_cfg));
  914. dpni_cfg.adv.options = DPNI_OPT_UNICAST_FILTER |
  915. DPNI_OPT_MULTICAST_FILTER;
  916. dpni_cfg.adv.ext_cfg_iova = (uint64_t)&ext_cfg_buf[0];
  917. err = dpni_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpni_cfg,
  918. &dflt_dpni->dpni_handle);
  919. if (err < 0) {
  920. err = -ENODEV;
  921. printf("dpni_create() failed: %d\n", err);
  922. goto err_create;
  923. }
  924. memset(&dpni_attr, 0, sizeof(struct dpni_attr));
  925. err = dpni_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS,
  926. dflt_dpni->dpni_handle,
  927. &dpni_attr);
  928. if (err < 0) {
  929. printf("dpni_get_attributes() failed: %d\n", err);
  930. goto err_get_attr;
  931. }
  932. if ((dpni_attr.version.major != DPNI_VER_MAJOR) ||
  933. (dpni_attr.version.minor != DPNI_VER_MINOR)) {
  934. printf("DPNI version mismatch found %u.%u,",
  935. dpni_attr.version.major, dpni_attr.version.minor);
  936. printf("supported version is %u.%u\n",
  937. DPNI_VER_MAJOR, DPNI_VER_MINOR);
  938. }
  939. dflt_dpni->dpni_id = dpni_attr.id;
  940. #ifdef DEBUG
  941. printf("Init: DPNI id=0x%d\n", dflt_dpni->dpni_id);
  942. #endif
  943. err = dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
  944. if (err < 0) {
  945. printf("dpni_close() failed: %d\n", err);
  946. goto err_close;
  947. }
  948. return 0;
  949. err_close:
  950. err_get_attr:
  951. dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
  952. dpni_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
  953. err_create:
  954. err_prepare_extended_cfg:
  955. free(dflt_dpni);
  956. err_malloc:
  957. return err;
  958. }
  959. static int dpni_exit(void)
  960. {
  961. int err;
  962. err = dpni_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_id,
  963. &dflt_dpni->dpni_handle);
  964. if (err < 0) {
  965. printf("dpni_open() failed: %d\n", err);
  966. goto err;
  967. }
  968. err = dpni_destroy(dflt_mc_io, MC_CMD_NO_FLAGS,
  969. dflt_dpni->dpni_handle);
  970. if (err < 0) {
  971. printf("dpni_destroy() failed: %d\n", err);
  972. goto err;
  973. }
  974. #ifdef DEBUG
  975. printf("Exit: DPNI id=0x%d\n", dflt_dpni->dpni_id);
  976. #endif
  977. if (dflt_dpni)
  978. free(dflt_dpni);
  979. return 0;
  980. err:
  981. return err;
  982. }
  983. static int mc_init_object(void)
  984. {
  985. int err = 0;
  986. err = dprc_init();
  987. if (err < 0) {
  988. printf("dprc_init() failed: %d\n", err);
  989. goto err;
  990. }
  991. err = dpbp_init();
  992. if (err < 0) {
  993. printf("dpbp_init() failed: %d\n", err);
  994. goto err;
  995. }
  996. err = dpio_init();
  997. if (err < 0) {
  998. printf("dpio_init() failed: %d\n", err);
  999. goto err;
  1000. }
  1001. err = dpni_init();
  1002. if (err < 0) {
  1003. printf("dpni_init() failed: %d\n", err);
  1004. goto err;
  1005. }
  1006. return 0;
  1007. err:
  1008. return err;
  1009. }
  1010. int fsl_mc_ldpaa_exit(bd_t *bd)
  1011. {
  1012. int err = 0;
  1013. bool is_dpl_apply_status = false;
  1014. if (bd && mc_lazy_dpl_addr && !fsl_mc_ldpaa_exit(NULL)) {
  1015. mc_apply_dpl(mc_lazy_dpl_addr);
  1016. mc_lazy_dpl_addr = 0;
  1017. }
  1018. /* MC is not loaded intentionally, So return success. */
  1019. if (bd && get_mc_boot_status() != 0)
  1020. return 0;
  1021. /* If DPL is deployed, set is_dpl_apply_status as TRUE. */
  1022. if (!get_dpl_apply_status())
  1023. is_dpl_apply_status = true;
  1024. /*
  1025. * For case MC is loaded but DPL is not deployed, return success and
  1026. * print message on console. Else FDT fix-up code execution hanged.
  1027. */
  1028. if (bd && !get_mc_boot_status() && !is_dpl_apply_status) {
  1029. printf("fsl-mc: DPL not deployed, DPAA2 ethernet not work\n");
  1030. return 0;
  1031. }
  1032. err = dpbp_exit();
  1033. if (err < 0) {
  1034. printf("dpbp_exit() failed: %d\n", err);
  1035. goto err;
  1036. }
  1037. err = dpio_exit();
  1038. if (err < 0) {
  1039. printf("dpio_exit() failed: %d\n", err);
  1040. goto err;
  1041. }
  1042. err = dpni_exit();
  1043. if (err < 0) {
  1044. printf("dpni_exit() failed: %d\n", err);
  1045. goto err;
  1046. }
  1047. err = dprc_exit();
  1048. if (err < 0) {
  1049. printf("dprc_exit() failed: %d\n", err);
  1050. goto err;
  1051. }
  1052. return 0;
  1053. err:
  1054. return err;
  1055. }
  1056. static int do_fsl_mc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  1057. {
  1058. int err = 0;
  1059. if (argc < 3)
  1060. goto usage;
  1061. switch (argv[1][0]) {
  1062. case 's': {
  1063. char sub_cmd;
  1064. u64 mc_fw_addr, mc_dpc_addr;
  1065. #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET
  1066. u64 aiop_fw_addr;
  1067. #endif
  1068. sub_cmd = argv[2][0];
  1069. switch (sub_cmd) {
  1070. case 'm':
  1071. if (argc < 5)
  1072. goto usage;
  1073. if (get_mc_boot_status() == 0) {
  1074. printf("fsl-mc: MC is already booted");
  1075. printf("\n");
  1076. return err;
  1077. }
  1078. mc_fw_addr = simple_strtoull(argv[3], NULL, 16);
  1079. mc_dpc_addr = simple_strtoull(argv[4], NULL,
  1080. 16);
  1081. if (!mc_init(mc_fw_addr, mc_dpc_addr))
  1082. err = mc_init_object();
  1083. break;
  1084. #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET
  1085. case 'a':
  1086. if (argc < 4)
  1087. goto usage;
  1088. if (get_aiop_apply_status() == 0) {
  1089. printf("fsl-mc: AIOP FW is already");
  1090. printf(" applied\n");
  1091. return err;
  1092. }
  1093. aiop_fw_addr = simple_strtoull(argv[3], NULL,
  1094. 16);
  1095. /* if SoC doesn't have AIOP, err = -ENODEV */
  1096. err = load_mc_aiop_img(aiop_fw_addr);
  1097. if (!err)
  1098. printf("fsl-mc: AIOP FW applied\n");
  1099. break;
  1100. #endif
  1101. default:
  1102. printf("Invalid option: %s\n", argv[2]);
  1103. goto usage;
  1104. break;
  1105. }
  1106. }
  1107. break;
  1108. case 'l':
  1109. case 'a': {
  1110. u64 mc_dpl_addr;
  1111. if (argc < 4)
  1112. goto usage;
  1113. if (get_dpl_apply_status() == 0) {
  1114. printf("fsl-mc: DPL already applied\n");
  1115. return err;
  1116. }
  1117. mc_dpl_addr = simple_strtoull(argv[3], NULL,
  1118. 16);
  1119. if (get_mc_boot_status() != 0) {
  1120. printf("fsl-mc: Deploying data path layout ..");
  1121. printf("ERROR (MC is not booted)\n");
  1122. return -ENODEV;
  1123. }
  1124. if (argv[1][0] == 'l') {
  1125. /*
  1126. * We will do the actual dpaa exit and dpl apply
  1127. * later from announce_and_cleanup().
  1128. */
  1129. mc_lazy_dpl_addr = mc_dpl_addr;
  1130. } else {
  1131. /* The user wants it applied now */
  1132. if (!fsl_mc_ldpaa_exit(NULL))
  1133. err = mc_apply_dpl(mc_dpl_addr);
  1134. }
  1135. break;
  1136. }
  1137. default:
  1138. printf("Invalid option: %s\n", argv[1]);
  1139. goto usage;
  1140. break;
  1141. }
  1142. return err;
  1143. usage:
  1144. return CMD_RET_USAGE;
  1145. }
  1146. U_BOOT_CMD(
  1147. fsl_mc, CONFIG_SYS_MAXARGS, 1, do_fsl_mc,
  1148. "DPAA2 command to manage Management Complex (MC)",
  1149. "start mc [FW_addr] [DPC_addr] - Start Management Complex\n"
  1150. "fsl_mc apply DPL [DPL_addr] - Apply DPL file\n"
  1151. "fsl_mc lazyapply DPL [DPL_addr] - Apply DPL file on exit\n"
  1152. "fsl_mc start aiop [FW_addr] - Start AIOP\n"
  1153. );