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