Merge branch 'master' of git://www.denx.de/git/u-boot-socfpga
[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 <errno.h>
7 #include <asm/io.h>
8 #include <fsl-mc/fsl_mc.h>
9 #include <fsl-mc/fsl_mc_sys.h>
10 #include <fsl-mc/fsl_mc_private.h>
11 #include <fsl-mc/fsl_dpmng.h>
12 #include <fsl_debug_server.h>
13 #include <fsl-mc/fsl_dprc.h>
14 #include <fsl-mc/fsl_dpio.h>
15 #include <fsl-mc/fsl_qbman_portal.h>
16
17 #define MC_RAM_BASE_ADDR_ALIGNMENT  (512UL * 1024 * 1024)
18 #define MC_RAM_BASE_ADDR_ALIGNMENT_MASK (~(MC_RAM_BASE_ADDR_ALIGNMENT - 1))
19 #define MC_RAM_SIZE_ALIGNMENT       (256UL * 1024 * 1024)
20
21 #define MC_MEM_SIZE_ENV_VAR     "mcmemsize"
22 #define MC_BOOT_TIMEOUT_ENV_VAR "mcboottimeout"
23
24 DECLARE_GLOBAL_DATA_PTR;
25 static int mc_boot_status;
26 struct fsl_mc_io *dflt_mc_io = NULL;
27 uint16_t dflt_dprc_handle = 0;
28 struct fsl_dpbp_obj *dflt_dpbp = NULL;
29 struct fsl_dpio_obj *dflt_dpio = NULL;
30 uint16_t dflt_dpio_handle = 0;
31
32 #ifdef DEBUG
33 void dump_ram_words(const char *title, void *addr)
34 {
35         int i;
36         uint32_t *words = addr;
37
38         printf("Dumping beginning of %s (%p):\n", title, addr);
39         for (i = 0; i < 16; i++)
40                 printf("%#x ", words[i]);
41
42         printf("\n");
43 }
44
45 void dump_mc_ccsr_regs(struct mc_ccsr_registers __iomem *mc_ccsr_regs)
46 {
47         printf("MC CCSR registers:\n"
48                 "reg_gcr1 %#x\n"
49                 "reg_gsr %#x\n"
50                 "reg_sicbalr %#x\n"
51                 "reg_sicbahr %#x\n"
52                 "reg_sicapr %#x\n"
53                 "reg_mcfbalr %#x\n"
54                 "reg_mcfbahr %#x\n"
55                 "reg_mcfapr %#x\n"
56                 "reg_psr %#x\n",
57                 mc_ccsr_regs->reg_gcr1,
58                 mc_ccsr_regs->reg_gsr,
59                 mc_ccsr_regs->reg_sicbalr,
60                 mc_ccsr_regs->reg_sicbahr,
61                 mc_ccsr_regs->reg_sicapr,
62                 mc_ccsr_regs->reg_mcfbalr,
63                 mc_ccsr_regs->reg_mcfbahr,
64                 mc_ccsr_regs->reg_mcfapr,
65                 mc_ccsr_regs->reg_psr);
66 }
67 #else
68
69 #define dump_ram_words(title, addr)
70 #define dump_mc_ccsr_regs(mc_ccsr_regs)
71
72 #endif /* DEBUG */
73
74 #ifndef CONFIG_SYS_LS_MC_FW_IN_DDR
75 /**
76  * Copying MC firmware or DPL image to DDR
77  */
78 static int mc_copy_image(const char *title,
79                          u64 image_addr, u32 image_size, u64 mc_ram_addr)
80 {
81         debug("%s copied to address %p\n", title, (void *)mc_ram_addr);
82         memcpy((void *)mc_ram_addr, (void *)image_addr, image_size);
83         flush_dcache_range(mc_ram_addr, mc_ram_addr + image_size);
84         return 0;
85 }
86
87 /**
88  * MC firmware FIT image parser checks if the image is in FIT
89  * format, verifies integrity of the image and calculates
90  * raw image address and size values.
91  * Returns 0 on success and a negative errno on error.
92  * task fail.
93  **/
94 int parse_mc_firmware_fit_image(const void **raw_image_addr,
95                                 size_t *raw_image_size)
96 {
97         int format;
98         void *fit_hdr;
99         int node_offset;
100         const void *data;
101         size_t size;
102         const char *uname = "firmware";
103
104         /* Check if the image is in NOR flash */
105 #ifdef CONFIG_SYS_LS_MC_FW_IN_NOR
106         fit_hdr = (void *)CONFIG_SYS_LS_MC_FW_ADDR;
107 #else
108 #error "No CONFIG_SYS_LS_MC_FW_IN_xxx defined"
109 #endif
110
111         /* Check if Image is in FIT format */
112         format = genimg_get_format(fit_hdr);
113
114         if (format != IMAGE_FORMAT_FIT) {
115                 printf("fsl-mc: ERROR: Bad firmware image (not a FIT image)\n");
116                 return -EINVAL;
117         }
118
119         if (!fit_check_format(fit_hdr)) {
120                 printf("fsl-mc: ERROR: Bad firmware image (bad FIT header)\n");
121                 return -EINVAL;
122         }
123
124         node_offset = fit_image_get_node(fit_hdr, uname);
125
126         if (node_offset < 0) {
127                 printf("fsl-mc: ERROR: Bad firmware image (missing subimage)\n");
128                 return -ENOENT;
129         }
130
131         /* Verify MC firmware image */
132         if (!(fit_image_verify(fit_hdr, node_offset))) {
133                 printf("fsl-mc: ERROR: Bad firmware image (bad CRC)\n");
134                 return -EINVAL;
135         }
136
137         /* Get address and size of raw image */
138         fit_image_get_data(fit_hdr, node_offset, &data, &size);
139
140         *raw_image_addr = data;
141         *raw_image_size = size;
142
143         return 0;
144 }
145 #endif
146
147 /*
148  * Calculates the values to be used to specify the address range
149  * for the MC private DRAM block, in the MCFBALR/MCFBAHR registers.
150  * It returns the highest 512MB-aligned address within the given
151  * address range, in '*aligned_base_addr', and the number of 256 MiB
152  * blocks in it, in 'num_256mb_blocks'.
153  */
154 static int calculate_mc_private_ram_params(u64 mc_private_ram_start_addr,
155                                            size_t mc_ram_size,
156                                            u64 *aligned_base_addr,
157                                            u8 *num_256mb_blocks)
158 {
159         u64 addr;
160         u16 num_blocks;
161
162         if (mc_ram_size % MC_RAM_SIZE_ALIGNMENT != 0) {
163                 printf("fsl-mc: ERROR: invalid MC private RAM size (%lu)\n",
164                        mc_ram_size);
165                 return -EINVAL;
166         }
167
168         num_blocks = mc_ram_size / MC_RAM_SIZE_ALIGNMENT;
169         if (num_blocks < 1 || num_blocks > 0xff) {
170                 printf("fsl-mc: ERROR: invalid MC private RAM size (%lu)\n",
171                        mc_ram_size);
172                 return -EINVAL;
173         }
174
175         addr = (mc_private_ram_start_addr + mc_ram_size - 1) &
176                 MC_RAM_BASE_ADDR_ALIGNMENT_MASK;
177
178         if (addr < mc_private_ram_start_addr) {
179                 printf("fsl-mc: ERROR: bad start address %#llx\n",
180                        mc_private_ram_start_addr);
181                 return -EFAULT;
182         }
183
184         *aligned_base_addr = addr;
185         *num_256mb_blocks = num_blocks;
186         return 0;
187 }
188
189 static int load_mc_dpc(u64 mc_ram_addr, size_t mc_ram_size)
190 {
191         u64 mc_dpc_offset;
192 #ifndef CONFIG_SYS_LS_MC_DPC_IN_DDR
193         int error;
194         void *dpc_fdt_hdr;
195         int dpc_size;
196 #endif
197
198 #ifdef CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET
199         BUILD_BUG_ON((CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET & 0x3) != 0 ||
200                      CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET > 0xffffffff);
201
202         mc_dpc_offset = CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET;
203 #else
204 #error "CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET not defined"
205 #endif
206
207         /*
208          * Load the MC DPC blob in the MC private DRAM block:
209          */
210 #ifdef CONFIG_SYS_LS_MC_DPC_IN_DDR
211         printf("MC DPC is preloaded to %#llx\n", mc_ram_addr + mc_dpc_offset);
212 #else
213         /*
214          * Get address and size of the DPC blob stored in flash:
215          */
216 #ifdef CONFIG_SYS_LS_MC_DPC_IN_NOR
217         dpc_fdt_hdr = (void *)CONFIG_SYS_LS_MC_DPC_ADDR;
218 #else
219 #error "No CONFIG_SYS_LS_MC_DPC_IN_xxx defined"
220 #endif
221
222         error = fdt_check_header(dpc_fdt_hdr);
223         if (error != 0) {
224                 /*
225                  * Don't return with error here, since the MC firmware can
226                  * still boot without a DPC
227                  */
228                 printf("fsl-mc: WARNING: No DPC image found\n");
229                 return 0;
230         }
231
232         dpc_size = fdt_totalsize(dpc_fdt_hdr);
233         if (dpc_size > CONFIG_SYS_LS_MC_DPC_MAX_LENGTH) {
234                 printf("fsl-mc: ERROR: Bad DPC image (too large: %d)\n",
235                        dpc_size);
236                 return -EINVAL;
237         }
238
239         mc_copy_image("MC DPC blob",
240                       (u64)dpc_fdt_hdr, dpc_size, mc_ram_addr + mc_dpc_offset);
241 #endif /* not defined CONFIG_SYS_LS_MC_DPC_IN_DDR */
242
243         dump_ram_words("DPC", (void *)(mc_ram_addr + mc_dpc_offset));
244         return 0;
245 }
246
247 static int load_mc_dpl(u64 mc_ram_addr, size_t mc_ram_size)
248 {
249         u64 mc_dpl_offset;
250 #ifndef CONFIG_SYS_LS_MC_DPL_IN_DDR
251         int error;
252         void *dpl_fdt_hdr;
253         int dpl_size;
254 #endif
255
256 #ifdef CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET
257         BUILD_BUG_ON((CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET & 0x3) != 0 ||
258                      CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET > 0xffffffff);
259
260         mc_dpl_offset = CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET;
261 #else
262 #error "CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET not defined"
263 #endif
264
265         /*
266          * Load the MC DPL blob in the MC private DRAM block:
267          */
268 #ifdef CONFIG_SYS_LS_MC_DPL_IN_DDR
269         printf("MC DPL is preloaded to %#llx\n", mc_ram_addr + mc_dpl_offset);
270 #else
271         /*
272          * Get address and size of the DPL blob stored in flash:
273          */
274 #ifdef CONFIG_SYS_LS_MC_DPL_IN_NOR
275         dpl_fdt_hdr = (void *)CONFIG_SYS_LS_MC_DPL_ADDR;
276 #else
277 #error "No CONFIG_SYS_LS_MC_DPL_IN_xxx defined"
278 #endif
279
280         error = fdt_check_header(dpl_fdt_hdr);
281         if (error != 0) {
282                 printf("fsl-mc: ERROR: Bad DPL image (bad header)\n");
283                 return error;
284         }
285
286         dpl_size = fdt_totalsize(dpl_fdt_hdr);
287         if (dpl_size > CONFIG_SYS_LS_MC_DPL_MAX_LENGTH) {
288                 printf("fsl-mc: ERROR: Bad DPL image (too large: %d)\n",
289                        dpl_size);
290                 return -EINVAL;
291         }
292
293         mc_copy_image("MC DPL blob",
294                       (u64)dpl_fdt_hdr, dpl_size, mc_ram_addr + mc_dpl_offset);
295 #endif /* not defined CONFIG_SYS_LS_MC_DPL_IN_DDR */
296
297         dump_ram_words("DPL", (void *)(mc_ram_addr + mc_dpl_offset));
298         return 0;
299 }
300
301 /**
302  * Return the MC boot timeout value in milliseconds
303  */
304 static unsigned long get_mc_boot_timeout_ms(void)
305 {
306         unsigned long timeout_ms = CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS;
307
308         char *timeout_ms_env_var = getenv(MC_BOOT_TIMEOUT_ENV_VAR);
309
310         if (timeout_ms_env_var) {
311                 timeout_ms = simple_strtoul(timeout_ms_env_var, NULL, 10);
312                 if (timeout_ms == 0) {
313                         printf("fsl-mc: WARNING: Invalid value for \'"
314                                MC_BOOT_TIMEOUT_ENV_VAR
315                                "\' environment variable: %lu\n",
316                                timeout_ms);
317
318                         timeout_ms = CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS;
319                 }
320         }
321
322         return timeout_ms;
323 }
324
325 static int wait_for_mc(bool booting_mc, u32 *final_reg_gsr)
326 {
327         u32 reg_gsr;
328         u32 mc_fw_boot_status;
329         unsigned long timeout_ms = get_mc_boot_timeout_ms();
330         struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR;
331
332         dmb();
333         debug("Polling mc_ccsr_regs->reg_gsr ...\n");
334         assert(timeout_ms > 0);
335         for (;;) {
336                 udelay(1000);   /* throttle polling */
337                 reg_gsr = in_le32(&mc_ccsr_regs->reg_gsr);
338                 mc_fw_boot_status = (reg_gsr & GSR_FS_MASK);
339                 if (mc_fw_boot_status & 0x1)
340                         break;
341
342                 timeout_ms--;
343                 if (timeout_ms == 0)
344                         break;
345         }
346
347         if (timeout_ms == 0) {
348                 if (booting_mc)
349                         printf("fsl-mc: timeout booting management complex firmware\n");
350                 else
351                         printf("fsl-mc: timeout deploying data path layout\n");
352
353                 /* TODO: Get an error status from an MC CCSR register */
354                 return -ETIMEDOUT;
355         }
356
357         if (mc_fw_boot_status != 0x1) {
358                 /*
359                  * TODO: Identify critical errors from the GSR register's FS
360                  * field and for those errors, set error to -ENODEV or other
361                  * appropriate errno, so that the status property is set to
362                  * failure in the fsl,dprc device tree node.
363                  */
364                 if (booting_mc) {
365                         printf("fsl-mc: WARNING: Firmware booted with error (GSR: %#x)\n",
366                                reg_gsr);
367                 } else {
368                         printf("fsl-mc: WARNING: Data path layout deployed with error (GSR: %#x)\n",
369                                reg_gsr);
370                 }
371         }
372
373         *final_reg_gsr = reg_gsr;
374         return 0;
375 }
376
377 int mc_init(void)
378 {
379         int error = 0;
380         int portal_id = 0;
381         struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR;
382         u64 mc_ram_addr;
383         u32 reg_gsr;
384         u32 reg_mcfbalr;
385 #ifndef CONFIG_SYS_LS_MC_FW_IN_DDR
386         const void *raw_image_addr;
387         size_t raw_image_size = 0;
388 #endif
389         struct mc_version mc_ver_info;
390         u64 mc_ram_aligned_base_addr;
391         u8 mc_ram_num_256mb_blocks;
392         size_t mc_ram_size = mc_get_dram_block_size();
393
394         /*
395          * The MC private DRAM block was already carved at the end of DRAM
396          * by board_init_f() using CONFIG_SYS_MEM_TOP_HIDE:
397          */
398         if (gd->bd->bi_dram[1].start) {
399                 mc_ram_addr =
400                         gd->bd->bi_dram[1].start + gd->bd->bi_dram[1].size;
401         } else {
402                 mc_ram_addr =
403                         gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size;
404         }
405
406 #ifdef CONFIG_FSL_DEBUG_SERVER
407         /*
408          * FIXME: I don't think this is right. See get_dram_size_to_hide()
409          */
410                 mc_ram_addr -= debug_server_get_dram_block_size();
411 #endif
412
413         error = calculate_mc_private_ram_params(mc_ram_addr,
414                                                 mc_ram_size,
415                                                 &mc_ram_aligned_base_addr,
416                                                 &mc_ram_num_256mb_blocks);
417         if (error != 0)
418                 goto out;
419
420         /*
421          * Management Complex cores should be held at reset out of POR.
422          * U-boot should be the first software to touch MC. To be safe,
423          * we reset all cores again by setting GCR1 to 0. It doesn't do
424          * anything if they are held at reset. After we setup the firmware
425          * we kick off MC by deasserting the reset bit for core 0, and
426          * deasserting the reset bits for Command Portal Managers.
427          * The stop bits are not touched here. They are used to stop the
428          * cores when they are active. Setting stop bits doesn't stop the
429          * cores from fetching instructions when they are released from
430          * reset.
431          */
432         out_le32(&mc_ccsr_regs->reg_gcr1, 0);
433         dmb();
434
435 #ifdef CONFIG_SYS_LS_MC_FW_IN_DDR
436         printf("MC firmware is preloaded to %#llx\n", mc_ram_addr);
437 #else
438         error = parse_mc_firmware_fit_image(&raw_image_addr, &raw_image_size);
439         if (error != 0)
440                 goto out;
441         /*
442          * Load the MC FW at the beginning of the MC private DRAM block:
443          */
444         mc_copy_image("MC Firmware",
445                       (u64)raw_image_addr, raw_image_size, mc_ram_addr);
446 #endif
447         dump_ram_words("firmware", (void *)mc_ram_addr);
448
449         error = load_mc_dpc(mc_ram_addr, mc_ram_size);
450         if (error != 0)
451                 goto out;
452
453         error = load_mc_dpl(mc_ram_addr, mc_ram_size);
454         if (error != 0)
455                 goto out;
456
457         debug("mc_ccsr_regs %p\n", mc_ccsr_regs);
458         dump_mc_ccsr_regs(mc_ccsr_regs);
459
460         /*
461          * Tell MC what is the address range of the DRAM block assigned to it:
462          */
463         reg_mcfbalr = (u32)mc_ram_aligned_base_addr |
464                       (mc_ram_num_256mb_blocks - 1);
465         out_le32(&mc_ccsr_regs->reg_mcfbalr, reg_mcfbalr);
466         out_le32(&mc_ccsr_regs->reg_mcfbahr,
467                  (u32)(mc_ram_aligned_base_addr >> 32));
468         out_le32(&mc_ccsr_regs->reg_mcfapr, MCFAPR_BYPASS_ICID_MASK);
469
470         /*
471          * Tell the MC that we want delayed DPL deployment.
472          */
473         out_le32(&mc_ccsr_regs->reg_gsr, 0xDD00);
474
475         printf("\nfsl-mc: Booting Management Complex ...\n");
476
477         /*
478          * Deassert reset and release MC core 0 to run
479          */
480         out_le32(&mc_ccsr_regs->reg_gcr1, GCR1_P1_DE_RST | GCR1_M_ALL_DE_RST);
481         error = wait_for_mc(true, &reg_gsr);
482         if (error != 0)
483                 goto out;
484
485         /*
486          * TODO: need to obtain the portal_id for the root container from the
487          * DPL
488          */
489         portal_id = 0;
490
491         /*
492          * Initialize the global default MC portal
493          * And check that the MC firmware is responding portal commands:
494          */
495         dflt_mc_io = (struct fsl_mc_io *)malloc(sizeof(struct fsl_mc_io));
496         if (!dflt_mc_io) {
497                 printf(" No memory: malloc() failed\n");
498                 return -ENOMEM;
499         }
500
501         dflt_mc_io->mmio_regs = SOC_MC_PORTAL_ADDR(portal_id);
502         debug("Checking access to MC portal of root DPRC container (portal_id %d, portal physical addr %p)\n",
503               portal_id, dflt_mc_io->mmio_regs);
504
505         error = mc_get_version(dflt_mc_io, &mc_ver_info);
506         if (error != 0) {
507                 printf("fsl-mc: ERROR: Firmware version check failed (error: %d)\n",
508                        error);
509                 goto out;
510         }
511
512         if (MC_VER_MAJOR != mc_ver_info.major)
513                 printf("fsl-mc: ERROR: Firmware major version mismatch (found: %d, expected: %d)\n",
514                        mc_ver_info.major, MC_VER_MAJOR);
515
516         if (MC_VER_MINOR != mc_ver_info.minor)
517                 printf("fsl-mc: WARNING: Firmware minor version mismatch (found: %d, expected: %d)\n",
518                        mc_ver_info.minor, MC_VER_MINOR);
519
520         printf("fsl-mc: Management Complex booted (version: %d.%d.%d, boot status: %#x)\n",
521                mc_ver_info.major, mc_ver_info.minor, mc_ver_info.revision,
522                reg_gsr & GSR_FS_MASK);
523
524         /*
525          * Tell the MC to deploy the DPL:
526          */
527         out_le32(&mc_ccsr_regs->reg_gsr, 0x0);
528         printf("\nfsl-mc: Deploying data path layout ...\n");
529         error = wait_for_mc(false, &reg_gsr);
530         if (error != 0)
531                 goto out;
532 out:
533         if (error != 0)
534                 mc_boot_status = -error;
535         else
536                 mc_boot_status = 0;
537
538         return error;
539 }
540
541 int get_mc_boot_status(void)
542 {
543         return mc_boot_status;
544 }
545
546 /**
547  * Return the actual size of the MC private DRAM block.
548  */
549 unsigned long mc_get_dram_block_size(void)
550 {
551         unsigned long dram_block_size = CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE;
552
553         char *dram_block_size_env_var = getenv(MC_MEM_SIZE_ENV_VAR);
554
555         if (dram_block_size_env_var) {
556                 dram_block_size = simple_strtoul(dram_block_size_env_var, NULL,
557                                                  10);
558
559                 if (dram_block_size < CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE) {
560                         printf("fsl-mc: WARNING: Invalid value for \'"
561                                MC_MEM_SIZE_ENV_VAR
562                                "\' environment variable: %lu\n",
563                                dram_block_size);
564
565                         dram_block_size = CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE;
566                 }
567         }
568
569         return dram_block_size;
570 }
571
572 int dpio_init(struct dprc_obj_desc obj_desc)
573 {
574         struct qbman_swp_desc p_des;
575         struct dpio_attr attr;
576         int err = 0;
577
578         dflt_dpio = (struct fsl_dpio_obj *)malloc(sizeof(struct fsl_dpio_obj));
579         if (!dflt_dpio) {
580                 printf(" No memory: malloc() failed\n");
581                 return -ENOMEM;
582         }
583
584         dflt_dpio->dpio_id = obj_desc.id;
585
586         err = dpio_open(dflt_mc_io, obj_desc.id, &dflt_dpio_handle);
587         if (err) {
588                 printf("dpio_open() failed\n");
589                 goto err_open;
590         }
591
592         err = dpio_get_attributes(dflt_mc_io, dflt_dpio_handle, &attr);
593         if (err) {
594                 printf("dpio_get_attributes() failed %d\n", err);
595                 goto err_get_attr;
596         }
597
598         err = dpio_enable(dflt_mc_io, dflt_dpio_handle);
599         if (err) {
600                 printf("dpio_enable() failed %d\n", err);
601                 goto err_get_enable;
602         }
603         debug("ce_paddr=0x%llx, ci_paddr=0x%llx, portalid=%d, prios=%d\n",
604               attr.qbman_portal_ce_paddr,
605               attr.qbman_portal_ci_paddr,
606               attr.qbman_portal_id,
607               attr.num_priorities);
608
609         p_des.cena_bar = (void *)attr.qbman_portal_ce_paddr;
610         p_des.cinh_bar = (void *)attr.qbman_portal_ci_paddr;
611
612         dflt_dpio->sw_portal = qbman_swp_init(&p_des);
613         if (dflt_dpio->sw_portal == NULL) {
614                 printf("qbman_swp_init() failed\n");
615                 goto err_get_swp_init;
616         }
617         return 0;
618
619 err_get_swp_init:
620 err_get_enable:
621         dpio_disable(dflt_mc_io, dflt_dpio_handle);
622 err_get_attr:
623         dpio_close(dflt_mc_io, dflt_dpio_handle);
624 err_open:
625         free(dflt_dpio);
626         return err;
627 }
628
629 int dpbp_init(struct dprc_obj_desc obj_desc)
630 {
631         dflt_dpbp = (struct fsl_dpbp_obj *)malloc(sizeof(struct fsl_dpbp_obj));
632         if (!dflt_dpbp) {
633                 printf(" No memory: malloc() failed\n");
634                 return -ENOMEM;
635         }
636         dflt_dpbp->dpbp_attr.id = obj_desc.id;
637
638         return 0;
639 }
640
641 int dprc_init_container_obj(struct dprc_obj_desc obj_desc, uint16_t dprc_handle)
642 {
643         int error = 0, state = 0;
644         struct dprc_endpoint dpni_endpoint, dpmac_endpoint;
645         if (!strcmp(obj_desc.type, "dpbp")) {
646                 if (!dflt_dpbp) {
647                         error = dpbp_init(obj_desc);
648                         if (error < 0)
649                                 printf("dpbp_init failed\n");
650                 }
651         } else if (!strcmp(obj_desc.type, "dpio")) {
652                 if (!dflt_dpio) {
653                         error = dpio_init(obj_desc);
654                         if (error < 0)
655                                 printf("dpio_init failed\n");
656                 }
657         } else if (!strcmp(obj_desc.type, "dpni")) {
658                 strcpy(dpni_endpoint.type, obj_desc.type);
659                 dpni_endpoint.id = obj_desc.id;
660                 error = dprc_get_connection(dflt_mc_io, dprc_handle,
661                                      &dpni_endpoint, &dpmac_endpoint, &state);
662                 if (!strcmp(dpmac_endpoint.type, "dpmac"))
663                         error = ldpaa_eth_init(obj_desc);
664                 if (error < 0)
665                         printf("ldpaa_eth_init failed\n");
666         }
667
668         return error;
669 }
670
671 int dprc_scan_container_obj(uint16_t dprc_handle, char *obj_type, int i)
672 {
673         int error = 0;
674         struct dprc_obj_desc obj_desc;
675
676         memset((void *)&obj_desc, 0x00, sizeof(struct dprc_obj_desc));
677
678         error = dprc_get_obj(dflt_mc_io, dprc_handle,
679                              i, &obj_desc);
680         if (error < 0) {
681                 printf("dprc_get_obj(i=%d) failed: %d\n",
682                        i, error);
683                 return error;
684         }
685
686         if (!strcmp(obj_desc.type, obj_type)) {
687                 debug("Discovered object: type %s, id %d, req %s\n",
688                       obj_desc.type, obj_desc.id, obj_type);
689
690                 error = dprc_init_container_obj(obj_desc, dprc_handle);
691                 if (error < 0) {
692                         printf("dprc_init_container_obj(i=%d) failed: %d\n",
693                                i, error);
694                         return error;
695                 }
696         }
697
698         return error;
699 }
700
701 int fsl_mc_ldpaa_init(bd_t *bis)
702 {
703         int i, error = 0;
704         int dprc_opened = 0, container_id;
705         int num_child_objects = 0;
706
707         error = mc_init();
708         if (error < 0)
709                 goto error;
710
711         error = dprc_get_container_id(dflt_mc_io, &container_id);
712         if (error < 0) {
713                 printf("dprc_get_container_id() failed: %d\n", error);
714                 goto error;
715         }
716
717         debug("fsl-mc: Container id=0x%x\n", container_id);
718
719         error = dprc_open(dflt_mc_io, container_id, &dflt_dprc_handle);
720         if (error < 0) {
721                 printf("dprc_open() failed: %d\n", error);
722                 goto error;
723         }
724         dprc_opened = true;
725
726         error = dprc_get_obj_count(dflt_mc_io,
727                                    dflt_dprc_handle,
728                                    &num_child_objects);
729         if (error < 0) {
730                 printf("dprc_get_obj_count() failed: %d\n", error);
731                 goto error;
732         }
733         debug("Total child in container %d = %d\n", container_id,
734               num_child_objects);
735
736         if (num_child_objects != 0) {
737                 /*
738                  * Discover objects currently in the DPRC container in the MC:
739                  */
740                 for (i = 0; i < num_child_objects; i++)
741                         error = dprc_scan_container_obj(dflt_dprc_handle,
742                                                         "dpbp", i);
743
744                 for (i = 0; i < num_child_objects; i++)
745                         error = dprc_scan_container_obj(dflt_dprc_handle,
746                                                         "dpio", i);
747
748                 for (i = 0; i < num_child_objects; i++)
749                         error = dprc_scan_container_obj(dflt_dprc_handle,
750                                                         "dpni", i);
751         }
752 error:
753         if (dprc_opened)
754                 dprc_close(dflt_mc_io, dflt_dprc_handle);
755
756         return error;
757 }
758
759 void fsl_mc_ldpaa_exit(bd_t *bis)
760 {
761         int err;
762
763         if (get_mc_boot_status() == 0) {
764                 err = dpio_disable(dflt_mc_io, dflt_dpio_handle);
765                 if (err < 0) {
766                         printf("dpio_disable() failed: %d\n", err);
767                         return;
768                 }
769                 err = dpio_reset(dflt_mc_io, dflt_dpio_handle);
770                 if (err < 0) {
771                         printf("dpio_reset() failed: %d\n", err);
772                         return;
773                 }
774                 err = dpio_close(dflt_mc_io, dflt_dpio_handle);
775                 if (err < 0) {
776                         printf("dpio_close() failed: %d\n", err);
777                         return;
778                 }
779
780                 free(dflt_dpio);
781                 free(dflt_dpbp);
782         }
783
784         if (dflt_mc_io)
785                 free(dflt_mc_io);
786 }