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