17b3bd9a7SJ. German Rivera /* 27b3bd9a7SJ. German Rivera * Copyright (C) 2014 Freescale Semiconductor 37b3bd9a7SJ. German Rivera * 47b3bd9a7SJ. German Rivera * SPDX-License-Identifier: GPL-2.0+ 57b3bd9a7SJ. German Rivera */ 621c69870SStuart Yoder #include <common.h> 77b3bd9a7SJ. German Rivera #include <errno.h> 884b8bf6dSMasahiro Yamada #include <linux/bug.h> 97b3bd9a7SJ. German Rivera #include <asm/io.h> 1021c69870SStuart Yoder #include <libfdt.h> 11*5707dfb0SBogdan Purcareata #include <net.h> 1221c69870SStuart Yoder #include <fdt_support.h> 137b3bd9a7SJ. German Rivera #include <fsl-mc/fsl_mc.h> 147b3bd9a7SJ. German Rivera #include <fsl-mc/fsl_mc_sys.h> 15a2a55e51SPrabhakar Kushwaha #include <fsl-mc/fsl_mc_private.h> 167b3bd9a7SJ. German Rivera #include <fsl-mc/fsl_dpmng.h> 17a2a55e51SPrabhakar Kushwaha #include <fsl-mc/fsl_dprc.h> 18a2a55e51SPrabhakar Kushwaha #include <fsl-mc/fsl_dpio.h> 19fb4a87a7SPrabhakar Kushwaha #include <fsl-mc/fsl_dpni.h> 20a2a55e51SPrabhakar Kushwaha #include <fsl-mc/fsl_qbman_portal.h> 21fb4a87a7SPrabhakar Kushwaha #include <fsl-mc/ldpaa_wriop.h> 227b3bd9a7SJ. German Rivera 23125e2bc1SJ. German Rivera #define MC_RAM_BASE_ADDR_ALIGNMENT (512UL * 1024 * 1024) 24125e2bc1SJ. German Rivera #define MC_RAM_BASE_ADDR_ALIGNMENT_MASK (~(MC_RAM_BASE_ADDR_ALIGNMENT - 1)) 25125e2bc1SJ. German Rivera #define MC_RAM_SIZE_ALIGNMENT (256UL * 1024 * 1024) 26125e2bc1SJ. German Rivera 27125e2bc1SJ. German Rivera #define MC_MEM_SIZE_ENV_VAR "mcmemsize" 28125e2bc1SJ. German Rivera #define MC_BOOT_TIMEOUT_ENV_VAR "mcboottimeout" 29125e2bc1SJ. German Rivera 307b3bd9a7SJ. German Rivera DECLARE_GLOBAL_DATA_PTR; 31fb4a87a7SPrabhakar Kushwaha static int mc_boot_status = -1; 32fb4a87a7SPrabhakar Kushwaha static int mc_dpl_applied = -1; 33fb4a87a7SPrabhakar Kushwaha #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET 34fb4a87a7SPrabhakar Kushwaha static int mc_aiop_applied = -1; 35fb4a87a7SPrabhakar Kushwaha #endif 361730a17dSPrabhakar Kushwaha struct fsl_mc_io *root_mc_io = NULL; 371730a17dSPrabhakar Kushwaha struct fsl_mc_io *dflt_mc_io = NULL; /* child container */ 381730a17dSPrabhakar Kushwaha uint16_t root_dprc_handle = 0; 39a2a55e51SPrabhakar Kushwaha uint16_t dflt_dprc_handle = 0; 401730a17dSPrabhakar Kushwaha int child_dprc_id; 41a2a55e51SPrabhakar Kushwaha struct fsl_dpbp_obj *dflt_dpbp = NULL; 42a2a55e51SPrabhakar Kushwaha struct fsl_dpio_obj *dflt_dpio = NULL; 431730a17dSPrabhakar Kushwaha struct fsl_dpni_obj *dflt_dpni = NULL; 44b7b8410aSAlexander Graf static u64 mc_lazy_dpl_addr; 457b3bd9a7SJ. German Rivera 46125e2bc1SJ. German Rivera #ifdef DEBUG 47125e2bc1SJ. German Rivera void dump_ram_words(const char *title, void *addr) 48125e2bc1SJ. German Rivera { 49125e2bc1SJ. German Rivera int i; 50125e2bc1SJ. German Rivera uint32_t *words = addr; 51125e2bc1SJ. German Rivera 52125e2bc1SJ. German Rivera printf("Dumping beginning of %s (%p):\n", title, addr); 53125e2bc1SJ. German Rivera for (i = 0; i < 16; i++) 54125e2bc1SJ. German Rivera printf("%#x ", words[i]); 55125e2bc1SJ. German Rivera 56125e2bc1SJ. German Rivera printf("\n"); 57125e2bc1SJ. German Rivera } 58125e2bc1SJ. German Rivera 59125e2bc1SJ. German Rivera void dump_mc_ccsr_regs(struct mc_ccsr_registers __iomem *mc_ccsr_regs) 60125e2bc1SJ. German Rivera { 61125e2bc1SJ. German Rivera printf("MC CCSR registers:\n" 62125e2bc1SJ. German Rivera "reg_gcr1 %#x\n" 63125e2bc1SJ. German Rivera "reg_gsr %#x\n" 64125e2bc1SJ. German Rivera "reg_sicbalr %#x\n" 65125e2bc1SJ. German Rivera "reg_sicbahr %#x\n" 66125e2bc1SJ. German Rivera "reg_sicapr %#x\n" 67125e2bc1SJ. German Rivera "reg_mcfbalr %#x\n" 68125e2bc1SJ. German Rivera "reg_mcfbahr %#x\n" 69125e2bc1SJ. German Rivera "reg_mcfapr %#x\n" 70125e2bc1SJ. German Rivera "reg_psr %#x\n", 71125e2bc1SJ. German Rivera mc_ccsr_regs->reg_gcr1, 72125e2bc1SJ. German Rivera mc_ccsr_regs->reg_gsr, 73125e2bc1SJ. German Rivera mc_ccsr_regs->reg_sicbalr, 74125e2bc1SJ. German Rivera mc_ccsr_regs->reg_sicbahr, 75125e2bc1SJ. German Rivera mc_ccsr_regs->reg_sicapr, 76125e2bc1SJ. German Rivera mc_ccsr_regs->reg_mcfbalr, 77125e2bc1SJ. German Rivera mc_ccsr_regs->reg_mcfbahr, 78125e2bc1SJ. German Rivera mc_ccsr_regs->reg_mcfapr, 79125e2bc1SJ. German Rivera mc_ccsr_regs->reg_psr); 80125e2bc1SJ. German Rivera } 81125e2bc1SJ. German Rivera #else 82125e2bc1SJ. German Rivera 83125e2bc1SJ. German Rivera #define dump_ram_words(title, addr) 84125e2bc1SJ. German Rivera #define dump_mc_ccsr_regs(mc_ccsr_regs) 85125e2bc1SJ. German Rivera 86125e2bc1SJ. German Rivera #endif /* DEBUG */ 87125e2bc1SJ. German Rivera 88125e2bc1SJ. German Rivera #ifndef CONFIG_SYS_LS_MC_FW_IN_DDR 897b3bd9a7SJ. German Rivera /** 907b3bd9a7SJ. German Rivera * Copying MC firmware or DPL image to DDR 917b3bd9a7SJ. German Rivera */ 927b3bd9a7SJ. German Rivera static int mc_copy_image(const char *title, 937b3bd9a7SJ. German Rivera u64 image_addr, u32 image_size, u64 mc_ram_addr) 947b3bd9a7SJ. German Rivera { 957b3bd9a7SJ. German Rivera debug("%s copied to address %p\n", title, (void *)mc_ram_addr); 967b3bd9a7SJ. German Rivera memcpy((void *)mc_ram_addr, (void *)image_addr, image_size); 97125e2bc1SJ. German Rivera flush_dcache_range(mc_ram_addr, mc_ram_addr + image_size); 987b3bd9a7SJ. German Rivera return 0; 997b3bd9a7SJ. German Rivera } 1007b3bd9a7SJ. German Rivera 1017b3bd9a7SJ. German Rivera /** 1027b3bd9a7SJ. German Rivera * MC firmware FIT image parser checks if the image is in FIT 1037b3bd9a7SJ. German Rivera * format, verifies integrity of the image and calculates 1047b3bd9a7SJ. German Rivera * raw image address and size values. 1057b3bd9a7SJ. German Rivera * Returns 0 on success and a negative errno on error. 1067b3bd9a7SJ. German Rivera * task fail. 1077b3bd9a7SJ. German Rivera **/ 108fb4a87a7SPrabhakar Kushwaha int parse_mc_firmware_fit_image(u64 mc_fw_addr, 109fb4a87a7SPrabhakar Kushwaha const void **raw_image_addr, 1107b3bd9a7SJ. German Rivera size_t *raw_image_size) 1117b3bd9a7SJ. German Rivera { 1127b3bd9a7SJ. German Rivera int format; 1137b3bd9a7SJ. German Rivera void *fit_hdr; 1147b3bd9a7SJ. German Rivera int node_offset; 1157b3bd9a7SJ. German Rivera const void *data; 1167b3bd9a7SJ. German Rivera size_t size; 1177b3bd9a7SJ. German Rivera const char *uname = "firmware"; 1187b3bd9a7SJ. German Rivera 119fb4a87a7SPrabhakar Kushwaha fit_hdr = (void *)mc_fw_addr; 1207b3bd9a7SJ. German Rivera 1217b3bd9a7SJ. German Rivera /* Check if Image is in FIT format */ 1227b3bd9a7SJ. German Rivera format = genimg_get_format(fit_hdr); 1237b3bd9a7SJ. German Rivera 1247b3bd9a7SJ. German Rivera if (format != IMAGE_FORMAT_FIT) { 125fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: ERR: Bad firmware image (not a FIT image)\n"); 1267b3bd9a7SJ. German Rivera return -EINVAL; 1277b3bd9a7SJ. German Rivera } 1287b3bd9a7SJ. German Rivera 1297b3bd9a7SJ. German Rivera if (!fit_check_format(fit_hdr)) { 130fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: ERR: Bad firmware image (bad FIT header)\n"); 1317b3bd9a7SJ. German Rivera return -EINVAL; 1327b3bd9a7SJ. German Rivera } 1337b3bd9a7SJ. German Rivera 1347b3bd9a7SJ. German Rivera node_offset = fit_image_get_node(fit_hdr, uname); 1357b3bd9a7SJ. German Rivera 1367b3bd9a7SJ. German Rivera if (node_offset < 0) { 137fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: ERR: Bad firmware image (missing subimage)\n"); 1387b3bd9a7SJ. German Rivera return -ENOENT; 1397b3bd9a7SJ. German Rivera } 1407b3bd9a7SJ. German Rivera 1417b3bd9a7SJ. German Rivera /* Verify MC firmware image */ 1427b3bd9a7SJ. German Rivera if (!(fit_image_verify(fit_hdr, node_offset))) { 143fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: ERR: Bad firmware image (bad CRC)\n"); 1447b3bd9a7SJ. German Rivera return -EINVAL; 1457b3bd9a7SJ. German Rivera } 1467b3bd9a7SJ. German Rivera 1477b3bd9a7SJ. German Rivera /* Get address and size of raw image */ 1487b3bd9a7SJ. German Rivera fit_image_get_data(fit_hdr, node_offset, &data, &size); 1497b3bd9a7SJ. German Rivera 1507b3bd9a7SJ. German Rivera *raw_image_addr = data; 1517b3bd9a7SJ. German Rivera *raw_image_size = size; 1527b3bd9a7SJ. German Rivera 1537b3bd9a7SJ. German Rivera return 0; 1547b3bd9a7SJ. German Rivera } 155125e2bc1SJ. German Rivera #endif 156125e2bc1SJ. German Rivera 157125e2bc1SJ. German Rivera /* 158125e2bc1SJ. German Rivera * Calculates the values to be used to specify the address range 159125e2bc1SJ. German Rivera * for the MC private DRAM block, in the MCFBALR/MCFBAHR registers. 160125e2bc1SJ. German Rivera * It returns the highest 512MB-aligned address within the given 161125e2bc1SJ. German Rivera * address range, in '*aligned_base_addr', and the number of 256 MiB 162125e2bc1SJ. German Rivera * blocks in it, in 'num_256mb_blocks'. 163125e2bc1SJ. German Rivera */ 164125e2bc1SJ. German Rivera static int calculate_mc_private_ram_params(u64 mc_private_ram_start_addr, 165125e2bc1SJ. German Rivera size_t mc_ram_size, 166125e2bc1SJ. German Rivera u64 *aligned_base_addr, 167125e2bc1SJ. German Rivera u8 *num_256mb_blocks) 168125e2bc1SJ. German Rivera { 169125e2bc1SJ. German Rivera u64 addr; 170125e2bc1SJ. German Rivera u16 num_blocks; 171125e2bc1SJ. German Rivera 172125e2bc1SJ. German Rivera if (mc_ram_size % MC_RAM_SIZE_ALIGNMENT != 0) { 173125e2bc1SJ. German Rivera printf("fsl-mc: ERROR: invalid MC private RAM size (%lu)\n", 174125e2bc1SJ. German Rivera mc_ram_size); 175125e2bc1SJ. German Rivera return -EINVAL; 176125e2bc1SJ. German Rivera } 177125e2bc1SJ. German Rivera 178125e2bc1SJ. German Rivera num_blocks = mc_ram_size / MC_RAM_SIZE_ALIGNMENT; 179125e2bc1SJ. German Rivera if (num_blocks < 1 || num_blocks > 0xff) { 180125e2bc1SJ. German Rivera printf("fsl-mc: ERROR: invalid MC private RAM size (%lu)\n", 181125e2bc1SJ. German Rivera mc_ram_size); 182125e2bc1SJ. German Rivera return -EINVAL; 183125e2bc1SJ. German Rivera } 184125e2bc1SJ. German Rivera 185125e2bc1SJ. German Rivera addr = (mc_private_ram_start_addr + mc_ram_size - 1) & 186125e2bc1SJ. German Rivera MC_RAM_BASE_ADDR_ALIGNMENT_MASK; 187125e2bc1SJ. German Rivera 188125e2bc1SJ. German Rivera if (addr < mc_private_ram_start_addr) { 189125e2bc1SJ. German Rivera printf("fsl-mc: ERROR: bad start address %#llx\n", 190125e2bc1SJ. German Rivera mc_private_ram_start_addr); 191125e2bc1SJ. German Rivera return -EFAULT; 192125e2bc1SJ. German Rivera } 193125e2bc1SJ. German Rivera 194125e2bc1SJ. German Rivera *aligned_base_addr = addr; 195125e2bc1SJ. German Rivera *num_256mb_blocks = num_blocks; 196125e2bc1SJ. German Rivera return 0; 197125e2bc1SJ. German Rivera } 198125e2bc1SJ. German Rivera 199*5707dfb0SBogdan Purcareata static int mc_fixup_dpc_mac_addr(void *blob, int noff, int dpmac_id, 200*5707dfb0SBogdan Purcareata struct eth_device *eth_dev) 201*5707dfb0SBogdan Purcareata { 202*5707dfb0SBogdan Purcareata int nodeoffset, err = 0; 203*5707dfb0SBogdan Purcareata char mac_name[10]; 204*5707dfb0SBogdan Purcareata const char link_type_mode[] = "FIXED_LINK"; 205*5707dfb0SBogdan Purcareata unsigned char env_enetaddr[6]; 206*5707dfb0SBogdan Purcareata 207*5707dfb0SBogdan Purcareata sprintf(mac_name, "mac@%d", dpmac_id); 208*5707dfb0SBogdan Purcareata 209*5707dfb0SBogdan Purcareata /* node not found - create it */ 210*5707dfb0SBogdan Purcareata nodeoffset = fdt_subnode_offset(blob, noff, (const char *) mac_name); 211*5707dfb0SBogdan Purcareata if (nodeoffset < 0) { 212*5707dfb0SBogdan Purcareata err = fdt_increase_size(blob, 200); 213*5707dfb0SBogdan Purcareata if (err) { 214*5707dfb0SBogdan Purcareata printf("fdt_increase_size: err=%s\n", 215*5707dfb0SBogdan Purcareata fdt_strerror(err)); 216*5707dfb0SBogdan Purcareata return err; 217*5707dfb0SBogdan Purcareata } 218*5707dfb0SBogdan Purcareata 219*5707dfb0SBogdan Purcareata nodeoffset = fdt_add_subnode(blob, noff, mac_name); 220*5707dfb0SBogdan Purcareata 221*5707dfb0SBogdan Purcareata /* add default property of fixed link */ 222*5707dfb0SBogdan Purcareata err = fdt_appendprop_string(blob, nodeoffset, 223*5707dfb0SBogdan Purcareata "link_type", link_type_mode); 224*5707dfb0SBogdan Purcareata if (err) { 225*5707dfb0SBogdan Purcareata printf("fdt_appendprop_string: err=%s\n", 226*5707dfb0SBogdan Purcareata fdt_strerror(err)); 227*5707dfb0SBogdan Purcareata return err; 228*5707dfb0SBogdan Purcareata } 229*5707dfb0SBogdan Purcareata } 230*5707dfb0SBogdan Purcareata 231*5707dfb0SBogdan Purcareata /* port_mac_address property present in DPC */ 232*5707dfb0SBogdan Purcareata if (fdt_get_property(blob, nodeoffset, "port_mac_address", NULL)) { 233*5707dfb0SBogdan Purcareata /* MAC addr randomly assigned - leave the one in DPC */ 234*5707dfb0SBogdan Purcareata eth_getenv_enetaddr_by_index("eth", eth_dev->index, 235*5707dfb0SBogdan Purcareata env_enetaddr); 236*5707dfb0SBogdan Purcareata if (is_zero_ethaddr(env_enetaddr)) 237*5707dfb0SBogdan Purcareata return err; 238*5707dfb0SBogdan Purcareata 239*5707dfb0SBogdan Purcareata /* replace DPC MAC address with u-boot env one */ 240*5707dfb0SBogdan Purcareata err = fdt_setprop(blob, nodeoffset, "port_mac_address", 241*5707dfb0SBogdan Purcareata eth_dev->enetaddr, 6); 242*5707dfb0SBogdan Purcareata if (err) { 243*5707dfb0SBogdan Purcareata printf("fdt_setprop mac: err=%s\n", fdt_strerror(err)); 244*5707dfb0SBogdan Purcareata return err; 245*5707dfb0SBogdan Purcareata } 246*5707dfb0SBogdan Purcareata 247*5707dfb0SBogdan Purcareata return 0; 248*5707dfb0SBogdan Purcareata } 249*5707dfb0SBogdan Purcareata 250*5707dfb0SBogdan Purcareata /* append port_mac_address property to mac node in DPC */ 251*5707dfb0SBogdan Purcareata err = fdt_increase_size(blob, 80); 252*5707dfb0SBogdan Purcareata if (err) { 253*5707dfb0SBogdan Purcareata printf("fdt_increase_size: err=%s\n", fdt_strerror(err)); 254*5707dfb0SBogdan Purcareata return err; 255*5707dfb0SBogdan Purcareata } 256*5707dfb0SBogdan Purcareata 257*5707dfb0SBogdan Purcareata err = fdt_appendprop(blob, nodeoffset, 258*5707dfb0SBogdan Purcareata "port_mac_address", eth_dev->enetaddr, 6); 259*5707dfb0SBogdan Purcareata if (err) { 260*5707dfb0SBogdan Purcareata printf("fdt_appendprop: err=%s\n", fdt_strerror(err)); 261*5707dfb0SBogdan Purcareata return err; 262*5707dfb0SBogdan Purcareata } 263*5707dfb0SBogdan Purcareata 264*5707dfb0SBogdan Purcareata return err; 265*5707dfb0SBogdan Purcareata } 266*5707dfb0SBogdan Purcareata 26721c69870SStuart Yoder static int mc_fixup_dpc(u64 dpc_addr) 26821c69870SStuart Yoder { 26921c69870SStuart Yoder void *blob = (void *)dpc_addr; 270*5707dfb0SBogdan Purcareata int nodeoffset, err = 0; 271*5707dfb0SBogdan Purcareata char ethname[10]; 272*5707dfb0SBogdan Purcareata struct eth_device *eth_dev; 273*5707dfb0SBogdan Purcareata int i; 27421c69870SStuart Yoder 27521c69870SStuart Yoder /* delete any existing ICID pools */ 27621c69870SStuart Yoder nodeoffset = fdt_path_offset(blob, "/resources/icid_pools"); 27721c69870SStuart Yoder if (fdt_del_node(blob, nodeoffset) < 0) 27821c69870SStuart Yoder printf("\nfsl-mc: WARNING: could not delete ICID pool\n"); 27921c69870SStuart Yoder 28021c69870SStuart Yoder /* add a new pool */ 28121c69870SStuart Yoder nodeoffset = fdt_path_offset(blob, "/resources"); 28221c69870SStuart Yoder if (nodeoffset < 0) { 28321c69870SStuart Yoder printf("\nfsl-mc: ERROR: DPC is missing /resources\n"); 28421c69870SStuart Yoder return -EINVAL; 28521c69870SStuart Yoder } 28621c69870SStuart Yoder nodeoffset = fdt_add_subnode(blob, nodeoffset, "icid_pools"); 28721c69870SStuart Yoder nodeoffset = fdt_add_subnode(blob, nodeoffset, "icid_pool@0"); 28821c69870SStuart Yoder do_fixup_by_path_u32(blob, "/resources/icid_pools/icid_pool@0", 28921c69870SStuart Yoder "base_icid", FSL_DPAA2_STREAM_ID_START, 1); 29021c69870SStuart Yoder do_fixup_by_path_u32(blob, "/resources/icid_pools/icid_pool@0", 29121c69870SStuart Yoder "num", 29221c69870SStuart Yoder FSL_DPAA2_STREAM_ID_END - 29321c69870SStuart Yoder FSL_DPAA2_STREAM_ID_START + 1, 1); 29421c69870SStuart Yoder 295*5707dfb0SBogdan Purcareata /* fixup MAC addresses for dpmac ports */ 296*5707dfb0SBogdan Purcareata nodeoffset = fdt_path_offset(blob, "/board_info/ports"); 297*5707dfb0SBogdan Purcareata if (nodeoffset < 0) 298*5707dfb0SBogdan Purcareata goto out; 299*5707dfb0SBogdan Purcareata 300*5707dfb0SBogdan Purcareata for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) { 301*5707dfb0SBogdan Purcareata /* port not enabled */ 302*5707dfb0SBogdan Purcareata if ((wriop_is_enabled_dpmac(i) != 1) || 303*5707dfb0SBogdan Purcareata (wriop_get_phy_address(i) == -1)) 304*5707dfb0SBogdan Purcareata continue; 305*5707dfb0SBogdan Purcareata 306*5707dfb0SBogdan Purcareata sprintf(ethname, "DPMAC%d@%s", i, 307*5707dfb0SBogdan Purcareata phy_interface_strings[wriop_get_enet_if(i)]); 308*5707dfb0SBogdan Purcareata 309*5707dfb0SBogdan Purcareata eth_dev = eth_get_dev_by_name(ethname); 310*5707dfb0SBogdan Purcareata if (eth_dev == NULL) 311*5707dfb0SBogdan Purcareata continue; 312*5707dfb0SBogdan Purcareata 313*5707dfb0SBogdan Purcareata err = mc_fixup_dpc_mac_addr(blob, nodeoffset, i, eth_dev); 314*5707dfb0SBogdan Purcareata if (err) { 315*5707dfb0SBogdan Purcareata printf("mc_fixup_dpc_mac_addr failed: err=%s\n", 316*5707dfb0SBogdan Purcareata fdt_strerror(err)); 317*5707dfb0SBogdan Purcareata goto out; 318*5707dfb0SBogdan Purcareata } 319*5707dfb0SBogdan Purcareata } 320*5707dfb0SBogdan Purcareata 321*5707dfb0SBogdan Purcareata out: 32221c69870SStuart Yoder flush_dcache_range(dpc_addr, dpc_addr + fdt_totalsize(blob)); 32321c69870SStuart Yoder 324*5707dfb0SBogdan Purcareata return err; 32521c69870SStuart Yoder } 32621c69870SStuart Yoder 327fb4a87a7SPrabhakar Kushwaha static int load_mc_dpc(u64 mc_ram_addr, size_t mc_ram_size, u64 mc_dpc_addr) 328125e2bc1SJ. German Rivera { 329125e2bc1SJ. German Rivera u64 mc_dpc_offset; 330125e2bc1SJ. German Rivera #ifndef CONFIG_SYS_LS_MC_DPC_IN_DDR 331125e2bc1SJ. German Rivera int error; 332125e2bc1SJ. German Rivera void *dpc_fdt_hdr; 333125e2bc1SJ. German Rivera int dpc_size; 334125e2bc1SJ. German Rivera #endif 335125e2bc1SJ. German Rivera 336125e2bc1SJ. German Rivera #ifdef CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET 337125e2bc1SJ. German Rivera BUILD_BUG_ON((CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET & 0x3) != 0 || 338125e2bc1SJ. German Rivera CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET > 0xffffffff); 339125e2bc1SJ. German Rivera 340125e2bc1SJ. German Rivera mc_dpc_offset = CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET; 341125e2bc1SJ. German Rivera #else 342125e2bc1SJ. German Rivera #error "CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET not defined" 343125e2bc1SJ. German Rivera #endif 344125e2bc1SJ. German Rivera 345125e2bc1SJ. German Rivera /* 346125e2bc1SJ. German Rivera * Load the MC DPC blob in the MC private DRAM block: 347125e2bc1SJ. German Rivera */ 348125e2bc1SJ. German Rivera #ifdef CONFIG_SYS_LS_MC_DPC_IN_DDR 349125e2bc1SJ. German Rivera printf("MC DPC is preloaded to %#llx\n", mc_ram_addr + mc_dpc_offset); 350125e2bc1SJ. German Rivera #else 351125e2bc1SJ. German Rivera /* 352125e2bc1SJ. German Rivera * Get address and size of the DPC blob stored in flash: 353125e2bc1SJ. German Rivera */ 354fb4a87a7SPrabhakar Kushwaha dpc_fdt_hdr = (void *)mc_dpc_addr; 355125e2bc1SJ. German Rivera 356125e2bc1SJ. German Rivera error = fdt_check_header(dpc_fdt_hdr); 357125e2bc1SJ. German Rivera if (error != 0) { 358125e2bc1SJ. German Rivera /* 359125e2bc1SJ. German Rivera * Don't return with error here, since the MC firmware can 360125e2bc1SJ. German Rivera * still boot without a DPC 361125e2bc1SJ. German Rivera */ 362cc088c3aSJ. German Rivera printf("\nfsl-mc: WARNING: No DPC image found"); 363125e2bc1SJ. German Rivera return 0; 364125e2bc1SJ. German Rivera } 365125e2bc1SJ. German Rivera 366125e2bc1SJ. German Rivera dpc_size = fdt_totalsize(dpc_fdt_hdr); 367125e2bc1SJ. German Rivera if (dpc_size > CONFIG_SYS_LS_MC_DPC_MAX_LENGTH) { 368cc088c3aSJ. German Rivera printf("\nfsl-mc: ERROR: Bad DPC image (too large: %d)\n", 369125e2bc1SJ. German Rivera dpc_size); 370125e2bc1SJ. German Rivera return -EINVAL; 371125e2bc1SJ. German Rivera } 372125e2bc1SJ. German Rivera 373125e2bc1SJ. German Rivera mc_copy_image("MC DPC blob", 374125e2bc1SJ. German Rivera (u64)dpc_fdt_hdr, dpc_size, mc_ram_addr + mc_dpc_offset); 375125e2bc1SJ. German Rivera #endif /* not defined CONFIG_SYS_LS_MC_DPC_IN_DDR */ 376125e2bc1SJ. German Rivera 37721c69870SStuart Yoder if (mc_fixup_dpc(mc_ram_addr + mc_dpc_offset)) 37821c69870SStuart Yoder return -EINVAL; 37921c69870SStuart Yoder 380125e2bc1SJ. German Rivera dump_ram_words("DPC", (void *)(mc_ram_addr + mc_dpc_offset)); 381125e2bc1SJ. German Rivera return 0; 382125e2bc1SJ. German Rivera } 383125e2bc1SJ. German Rivera 384fb4a87a7SPrabhakar Kushwaha static int load_mc_dpl(u64 mc_ram_addr, size_t mc_ram_size, u64 mc_dpl_addr) 385125e2bc1SJ. German Rivera { 386125e2bc1SJ. German Rivera u64 mc_dpl_offset; 387125e2bc1SJ. German Rivera #ifndef CONFIG_SYS_LS_MC_DPL_IN_DDR 388125e2bc1SJ. German Rivera int error; 389125e2bc1SJ. German Rivera void *dpl_fdt_hdr; 390125e2bc1SJ. German Rivera int dpl_size; 391125e2bc1SJ. German Rivera #endif 392125e2bc1SJ. German Rivera 393125e2bc1SJ. German Rivera #ifdef CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET 394125e2bc1SJ. German Rivera BUILD_BUG_ON((CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET & 0x3) != 0 || 395125e2bc1SJ. German Rivera CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET > 0xffffffff); 396125e2bc1SJ. German Rivera 397125e2bc1SJ. German Rivera mc_dpl_offset = CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET; 398125e2bc1SJ. German Rivera #else 399125e2bc1SJ. German Rivera #error "CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET not defined" 400125e2bc1SJ. German Rivera #endif 401125e2bc1SJ. German Rivera 402125e2bc1SJ. German Rivera /* 403125e2bc1SJ. German Rivera * Load the MC DPL blob in the MC private DRAM block: 404125e2bc1SJ. German Rivera */ 405125e2bc1SJ. German Rivera #ifdef CONFIG_SYS_LS_MC_DPL_IN_DDR 406125e2bc1SJ. German Rivera printf("MC DPL is preloaded to %#llx\n", mc_ram_addr + mc_dpl_offset); 407125e2bc1SJ. German Rivera #else 408125e2bc1SJ. German Rivera /* 409125e2bc1SJ. German Rivera * Get address and size of the DPL blob stored in flash: 410125e2bc1SJ. German Rivera */ 411fb4a87a7SPrabhakar Kushwaha dpl_fdt_hdr = (void *)mc_dpl_addr; 412125e2bc1SJ. German Rivera 413125e2bc1SJ. German Rivera error = fdt_check_header(dpl_fdt_hdr); 414125e2bc1SJ. German Rivera if (error != 0) { 415cc088c3aSJ. German Rivera printf("\nfsl-mc: ERROR: Bad DPL image (bad header)\n"); 416125e2bc1SJ. German Rivera return error; 417125e2bc1SJ. German Rivera } 418125e2bc1SJ. German Rivera 419125e2bc1SJ. German Rivera dpl_size = fdt_totalsize(dpl_fdt_hdr); 420125e2bc1SJ. German Rivera if (dpl_size > CONFIG_SYS_LS_MC_DPL_MAX_LENGTH) { 421cc088c3aSJ. German Rivera printf("\nfsl-mc: ERROR: Bad DPL image (too large: %d)\n", 422125e2bc1SJ. German Rivera dpl_size); 423125e2bc1SJ. German Rivera return -EINVAL; 424125e2bc1SJ. German Rivera } 425125e2bc1SJ. German Rivera 426125e2bc1SJ. German Rivera mc_copy_image("MC DPL blob", 427125e2bc1SJ. German Rivera (u64)dpl_fdt_hdr, dpl_size, mc_ram_addr + mc_dpl_offset); 428125e2bc1SJ. German Rivera #endif /* not defined CONFIG_SYS_LS_MC_DPL_IN_DDR */ 429125e2bc1SJ. German Rivera 430125e2bc1SJ. German Rivera dump_ram_words("DPL", (void *)(mc_ram_addr + mc_dpl_offset)); 431125e2bc1SJ. German Rivera return 0; 432125e2bc1SJ. German Rivera } 433125e2bc1SJ. German Rivera 434125e2bc1SJ. German Rivera /** 435125e2bc1SJ. German Rivera * Return the MC boot timeout value in milliseconds 436125e2bc1SJ. German Rivera */ 437125e2bc1SJ. German Rivera static unsigned long get_mc_boot_timeout_ms(void) 438125e2bc1SJ. German Rivera { 439125e2bc1SJ. German Rivera unsigned long timeout_ms = CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS; 440125e2bc1SJ. German Rivera 441125e2bc1SJ. German Rivera char *timeout_ms_env_var = getenv(MC_BOOT_TIMEOUT_ENV_VAR); 442125e2bc1SJ. German Rivera 443125e2bc1SJ. German Rivera if (timeout_ms_env_var) { 444125e2bc1SJ. German Rivera timeout_ms = simple_strtoul(timeout_ms_env_var, NULL, 10); 445125e2bc1SJ. German Rivera if (timeout_ms == 0) { 446125e2bc1SJ. German Rivera printf("fsl-mc: WARNING: Invalid value for \'" 447125e2bc1SJ. German Rivera MC_BOOT_TIMEOUT_ENV_VAR 448125e2bc1SJ. German Rivera "\' environment variable: %lu\n", 449125e2bc1SJ. German Rivera timeout_ms); 450125e2bc1SJ. German Rivera 451125e2bc1SJ. German Rivera timeout_ms = CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS; 452125e2bc1SJ. German Rivera } 453125e2bc1SJ. German Rivera } 454125e2bc1SJ. German Rivera 455125e2bc1SJ. German Rivera return timeout_ms; 456125e2bc1SJ. German Rivera } 457125e2bc1SJ. German Rivera 458fb4a87a7SPrabhakar Kushwaha #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET 4593c1d218aSYork Sun 4603c1d218aSYork Sun __weak bool soc_has_aiop(void) 4613c1d218aSYork Sun { 4623c1d218aSYork Sun return false; 4633c1d218aSYork Sun } 4643c1d218aSYork Sun 465fb4a87a7SPrabhakar Kushwaha static int load_mc_aiop_img(u64 aiop_fw_addr) 466c1000c12SJ. German Rivera { 467fb4a87a7SPrabhakar Kushwaha u64 mc_ram_addr = mc_get_dram_addr(); 468fb4a87a7SPrabhakar Kushwaha #ifndef CONFIG_SYS_LS_MC_DPC_IN_DDR 469c1000c12SJ. German Rivera void *aiop_img; 470fb4a87a7SPrabhakar Kushwaha #endif 471c1000c12SJ. German Rivera 4723c1d218aSYork Sun /* Check if AIOP is available */ 4733c1d218aSYork Sun if (!soc_has_aiop()) 4743c1d218aSYork Sun return -ENODEV; 475c1000c12SJ. German Rivera /* 476c1000c12SJ. German Rivera * Load the MC AIOP image in the MC private DRAM block: 477c1000c12SJ. German Rivera */ 478c1000c12SJ. German Rivera 479fb4a87a7SPrabhakar Kushwaha #ifdef CONFIG_SYS_LS_MC_DPC_IN_DDR 480fb4a87a7SPrabhakar Kushwaha printf("MC AIOP is preloaded to %#llx\n", mc_ram_addr + 481fb4a87a7SPrabhakar Kushwaha CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET); 482fb4a87a7SPrabhakar Kushwaha #else 483fb4a87a7SPrabhakar Kushwaha aiop_img = (void *)aiop_fw_addr; 484c1000c12SJ. German Rivera mc_copy_image("MC AIOP image", 485c1000c12SJ. German Rivera (u64)aiop_img, CONFIG_SYS_LS_MC_AIOP_IMG_MAX_LENGTH, 486c1000c12SJ. German Rivera mc_ram_addr + CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET); 487fb4a87a7SPrabhakar Kushwaha #endif 488fb4a87a7SPrabhakar Kushwaha mc_aiop_applied = 0; 489c1000c12SJ. German Rivera 490c1000c12SJ. German Rivera return 0; 491c1000c12SJ. German Rivera } 492c1000c12SJ. German Rivera #endif 493fb4a87a7SPrabhakar Kushwaha 494125e2bc1SJ. German Rivera static int wait_for_mc(bool booting_mc, u32 *final_reg_gsr) 495125e2bc1SJ. German Rivera { 496125e2bc1SJ. German Rivera u32 reg_gsr; 497125e2bc1SJ. German Rivera u32 mc_fw_boot_status; 498125e2bc1SJ. German Rivera unsigned long timeout_ms = get_mc_boot_timeout_ms(); 499125e2bc1SJ. German Rivera struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR; 500125e2bc1SJ. German Rivera 501125e2bc1SJ. German Rivera dmb(); 502125e2bc1SJ. German Rivera assert(timeout_ms > 0); 503125e2bc1SJ. German Rivera for (;;) { 504125e2bc1SJ. German Rivera udelay(1000); /* throttle polling */ 505125e2bc1SJ. German Rivera reg_gsr = in_le32(&mc_ccsr_regs->reg_gsr); 506125e2bc1SJ. German Rivera mc_fw_boot_status = (reg_gsr & GSR_FS_MASK); 507125e2bc1SJ. German Rivera if (mc_fw_boot_status & 0x1) 508125e2bc1SJ. German Rivera break; 509125e2bc1SJ. German Rivera 510125e2bc1SJ. German Rivera timeout_ms--; 511125e2bc1SJ. German Rivera if (timeout_ms == 0) 512125e2bc1SJ. German Rivera break; 513125e2bc1SJ. German Rivera } 514125e2bc1SJ. German Rivera 515125e2bc1SJ. German Rivera if (timeout_ms == 0) { 516cc088c3aSJ. German Rivera printf("ERROR: timeout\n"); 517125e2bc1SJ. German Rivera 518125e2bc1SJ. German Rivera /* TODO: Get an error status from an MC CCSR register */ 519125e2bc1SJ. German Rivera return -ETIMEDOUT; 520125e2bc1SJ. German Rivera } 521125e2bc1SJ. German Rivera 522125e2bc1SJ. German Rivera if (mc_fw_boot_status != 0x1) { 523125e2bc1SJ. German Rivera /* 524125e2bc1SJ. German Rivera * TODO: Identify critical errors from the GSR register's FS 525125e2bc1SJ. German Rivera * field and for those errors, set error to -ENODEV or other 526125e2bc1SJ. German Rivera * appropriate errno, so that the status property is set to 527125e2bc1SJ. German Rivera * failure in the fsl,dprc device tree node. 528125e2bc1SJ. German Rivera */ 529cc088c3aSJ. German Rivera printf("WARNING: Firmware returned an error (GSR: %#x)\n", 530125e2bc1SJ. German Rivera reg_gsr); 531125e2bc1SJ. German Rivera } else { 532cc088c3aSJ. German Rivera printf("SUCCESS\n"); 533125e2bc1SJ. German Rivera } 534cc088c3aSJ. German Rivera 535125e2bc1SJ. German Rivera 536125e2bc1SJ. German Rivera *final_reg_gsr = reg_gsr; 537125e2bc1SJ. German Rivera return 0; 538125e2bc1SJ. German Rivera } 5397b3bd9a7SJ. German Rivera 540fb4a87a7SPrabhakar Kushwaha int mc_init(u64 mc_fw_addr, u64 mc_dpc_addr) 5417b3bd9a7SJ. German Rivera { 5427b3bd9a7SJ. German Rivera int error = 0; 543a2a55e51SPrabhakar Kushwaha int portal_id = 0; 5447b3bd9a7SJ. German Rivera struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR; 545fb4a87a7SPrabhakar Kushwaha u64 mc_ram_addr = mc_get_dram_addr(); 5467b3bd9a7SJ. German Rivera u32 reg_gsr; 547125e2bc1SJ. German Rivera u32 reg_mcfbalr; 548125e2bc1SJ. German Rivera #ifndef CONFIG_SYS_LS_MC_FW_IN_DDR 5497b3bd9a7SJ. German Rivera const void *raw_image_addr; 5507b3bd9a7SJ. German Rivera size_t raw_image_size = 0; 551125e2bc1SJ. German Rivera #endif 5527b3bd9a7SJ. German Rivera struct mc_version mc_ver_info; 553125e2bc1SJ. German Rivera u64 mc_ram_aligned_base_addr; 554125e2bc1SJ. German Rivera u8 mc_ram_num_256mb_blocks; 555125e2bc1SJ. German Rivera size_t mc_ram_size = mc_get_dram_block_size(); 5567b3bd9a7SJ. German Rivera 5577b3bd9a7SJ. German Rivera 558125e2bc1SJ. German Rivera error = calculate_mc_private_ram_params(mc_ram_addr, 559125e2bc1SJ. German Rivera mc_ram_size, 560125e2bc1SJ. German Rivera &mc_ram_aligned_base_addr, 561125e2bc1SJ. German Rivera &mc_ram_num_256mb_blocks); 562125e2bc1SJ. German Rivera if (error != 0) 563125e2bc1SJ. German Rivera goto out; 564125e2bc1SJ. German Rivera 5657b3bd9a7SJ. German Rivera /* 5667b3bd9a7SJ. German Rivera * Management Complex cores should be held at reset out of POR. 567a187559eSBin Meng * U-Boot should be the first software to touch MC. To be safe, 5687b3bd9a7SJ. German Rivera * we reset all cores again by setting GCR1 to 0. It doesn't do 5697b3bd9a7SJ. German Rivera * anything if they are held at reset. After we setup the firmware 5707b3bd9a7SJ. German Rivera * we kick off MC by deasserting the reset bit for core 0, and 5717b3bd9a7SJ. German Rivera * deasserting the reset bits for Command Portal Managers. 5727b3bd9a7SJ. German Rivera * The stop bits are not touched here. They are used to stop the 5737b3bd9a7SJ. German Rivera * cores when they are active. Setting stop bits doesn't stop the 5747b3bd9a7SJ. German Rivera * cores from fetching instructions when they are released from 5757b3bd9a7SJ. German Rivera * reset. 5767b3bd9a7SJ. German Rivera */ 5777b3bd9a7SJ. German Rivera out_le32(&mc_ccsr_regs->reg_gcr1, 0); 5787b3bd9a7SJ. German Rivera dmb(); 5797b3bd9a7SJ. German Rivera 580125e2bc1SJ. German Rivera #ifdef CONFIG_SYS_LS_MC_FW_IN_DDR 581125e2bc1SJ. German Rivera printf("MC firmware is preloaded to %#llx\n", mc_ram_addr); 582125e2bc1SJ. German Rivera #else 583fb4a87a7SPrabhakar Kushwaha error = parse_mc_firmware_fit_image(mc_fw_addr, &raw_image_addr, 584fb4a87a7SPrabhakar Kushwaha &raw_image_size); 5857b3bd9a7SJ. German Rivera if (error != 0) 5867b3bd9a7SJ. German Rivera goto out; 5877b3bd9a7SJ. German Rivera /* 5887b3bd9a7SJ. German Rivera * Load the MC FW at the beginning of the MC private DRAM block: 5897b3bd9a7SJ. German Rivera */ 5907b3bd9a7SJ. German Rivera mc_copy_image("MC Firmware", 5917b3bd9a7SJ. German Rivera (u64)raw_image_addr, raw_image_size, mc_ram_addr); 5927b3bd9a7SJ. German Rivera #endif 593125e2bc1SJ. German Rivera dump_ram_words("firmware", (void *)mc_ram_addr); 5947b3bd9a7SJ. German Rivera 595fb4a87a7SPrabhakar Kushwaha error = load_mc_dpc(mc_ram_addr, mc_ram_size, mc_dpc_addr); 596125e2bc1SJ. German Rivera if (error != 0) 5977b3bd9a7SJ. German Rivera goto out; 5987b3bd9a7SJ. German Rivera 5997b3bd9a7SJ. German Rivera debug("mc_ccsr_regs %p\n", mc_ccsr_regs); 600125e2bc1SJ. German Rivera dump_mc_ccsr_regs(mc_ccsr_regs); 6017b3bd9a7SJ. German Rivera 6027b3bd9a7SJ. German Rivera /* 603125e2bc1SJ. German Rivera * Tell MC what is the address range of the DRAM block assigned to it: 6047b3bd9a7SJ. German Rivera */ 605125e2bc1SJ. German Rivera reg_mcfbalr = (u32)mc_ram_aligned_base_addr | 606125e2bc1SJ. German Rivera (mc_ram_num_256mb_blocks - 1); 607125e2bc1SJ. German Rivera out_le32(&mc_ccsr_regs->reg_mcfbalr, reg_mcfbalr); 608125e2bc1SJ. German Rivera out_le32(&mc_ccsr_regs->reg_mcfbahr, 609125e2bc1SJ. German Rivera (u32)(mc_ram_aligned_base_addr >> 32)); 61039da644eSStuart Yoder out_le32(&mc_ccsr_regs->reg_mcfapr, FSL_BYPASS_AMQ); 6117b3bd9a7SJ. German Rivera 6127b3bd9a7SJ. German Rivera /* 613125e2bc1SJ. German Rivera * Tell the MC that we want delayed DPL deployment. 6147b3bd9a7SJ. German Rivera */ 615125e2bc1SJ. German Rivera out_le32(&mc_ccsr_regs->reg_gsr, 0xDD00); 6167b3bd9a7SJ. German Rivera 617cc088c3aSJ. German Rivera printf("\nfsl-mc: Booting Management Complex ... "); 6187b3bd9a7SJ. German Rivera 6197b3bd9a7SJ. German Rivera /* 6207b3bd9a7SJ. German Rivera * Deassert reset and release MC core 0 to run 6217b3bd9a7SJ. German Rivera */ 6227b3bd9a7SJ. German Rivera out_le32(&mc_ccsr_regs->reg_gcr1, GCR1_P1_DE_RST | GCR1_M_ALL_DE_RST); 623125e2bc1SJ. German Rivera error = wait_for_mc(true, ®_gsr); 624125e2bc1SJ. German Rivera if (error != 0) 6257b3bd9a7SJ. German Rivera goto out; 6267b3bd9a7SJ. German Rivera 6277b3bd9a7SJ. German Rivera /* 6287b3bd9a7SJ. German Rivera * TODO: need to obtain the portal_id for the root container from the 6297b3bd9a7SJ. German Rivera * DPL 6307b3bd9a7SJ. German Rivera */ 6317b3bd9a7SJ. German Rivera portal_id = 0; 6327b3bd9a7SJ. German Rivera 6337b3bd9a7SJ. German Rivera /* 634a2a55e51SPrabhakar Kushwaha * Initialize the global default MC portal 635a2a55e51SPrabhakar Kushwaha * And check that the MC firmware is responding portal commands: 6367b3bd9a7SJ. German Rivera */ 6371730a17dSPrabhakar Kushwaha root_mc_io = (struct fsl_mc_io *)malloc(sizeof(struct fsl_mc_io)); 6381730a17dSPrabhakar Kushwaha if (!root_mc_io) { 639a2a55e51SPrabhakar Kushwaha printf(" No memory: malloc() failed\n"); 640a2a55e51SPrabhakar Kushwaha return -ENOMEM; 641a2a55e51SPrabhakar Kushwaha } 6427b3bd9a7SJ. German Rivera 6431730a17dSPrabhakar Kushwaha root_mc_io->mmio_regs = SOC_MC_PORTAL_ADDR(portal_id); 644a2a55e51SPrabhakar Kushwaha debug("Checking access to MC portal of root DPRC container (portal_id %d, portal physical addr %p)\n", 6451730a17dSPrabhakar Kushwaha portal_id, root_mc_io->mmio_regs); 646a2a55e51SPrabhakar Kushwaha 6471730a17dSPrabhakar Kushwaha error = mc_get_version(root_mc_io, MC_CMD_NO_FLAGS, &mc_ver_info); 6487b3bd9a7SJ. German Rivera if (error != 0) { 6497b3bd9a7SJ. German Rivera printf("fsl-mc: ERROR: Firmware version check failed (error: %d)\n", 6507b3bd9a7SJ. German Rivera error); 6517b3bd9a7SJ. German Rivera goto out; 6527b3bd9a7SJ. German Rivera } 6537b3bd9a7SJ. German Rivera 6547b3bd9a7SJ. German Rivera printf("fsl-mc: Management Complex booted (version: %d.%d.%d, boot status: %#x)\n", 6557b3bd9a7SJ. German Rivera mc_ver_info.major, mc_ver_info.minor, mc_ver_info.revision, 656125e2bc1SJ. German Rivera reg_gsr & GSR_FS_MASK); 657125e2bc1SJ. German Rivera 6587b3bd9a7SJ. German Rivera out: 6597b3bd9a7SJ. German Rivera if (error != 0) 6602b7c4a19SPrabhakar Kushwaha mc_boot_status = error; 6617b3bd9a7SJ. German Rivera else 6627b3bd9a7SJ. German Rivera mc_boot_status = 0; 6637b3bd9a7SJ. German Rivera 6647b3bd9a7SJ. German Rivera return error; 6657b3bd9a7SJ. German Rivera } 6667b3bd9a7SJ. German Rivera 667fb4a87a7SPrabhakar Kushwaha int mc_apply_dpl(u64 mc_dpl_addr) 668fb4a87a7SPrabhakar Kushwaha { 669fb4a87a7SPrabhakar Kushwaha struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR; 670fb4a87a7SPrabhakar Kushwaha int error = 0; 671fb4a87a7SPrabhakar Kushwaha u32 reg_gsr; 672fb4a87a7SPrabhakar Kushwaha u64 mc_ram_addr = mc_get_dram_addr(); 673fb4a87a7SPrabhakar Kushwaha size_t mc_ram_size = mc_get_dram_block_size(); 674fb4a87a7SPrabhakar Kushwaha 675b7b8410aSAlexander Graf if (!mc_dpl_addr) 676b7b8410aSAlexander Graf return -1; 677b7b8410aSAlexander Graf 678fb4a87a7SPrabhakar Kushwaha error = load_mc_dpl(mc_ram_addr, mc_ram_size, mc_dpl_addr); 679fb4a87a7SPrabhakar Kushwaha if (error != 0) 680fb4a87a7SPrabhakar Kushwaha return error; 681fb4a87a7SPrabhakar Kushwaha 682fb4a87a7SPrabhakar Kushwaha /* 683fb4a87a7SPrabhakar Kushwaha * Tell the MC to deploy the DPL: 684fb4a87a7SPrabhakar Kushwaha */ 685fb4a87a7SPrabhakar Kushwaha out_le32(&mc_ccsr_regs->reg_gsr, 0x0); 686fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: Deploying data path layout ... "); 687fb4a87a7SPrabhakar Kushwaha error = wait_for_mc(false, ®_gsr); 688fb4a87a7SPrabhakar Kushwaha 689fb4a87a7SPrabhakar Kushwaha if (!error) 690fb4a87a7SPrabhakar Kushwaha mc_dpl_applied = 0; 691fb4a87a7SPrabhakar Kushwaha 692fb4a87a7SPrabhakar Kushwaha return error; 693fb4a87a7SPrabhakar Kushwaha } 694fb4a87a7SPrabhakar Kushwaha 6957b3bd9a7SJ. German Rivera int get_mc_boot_status(void) 6967b3bd9a7SJ. German Rivera { 6977b3bd9a7SJ. German Rivera return mc_boot_status; 6987b3bd9a7SJ. German Rivera } 6997b3bd9a7SJ. German Rivera 700fb4a87a7SPrabhakar Kushwaha #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET 701fb4a87a7SPrabhakar Kushwaha int get_aiop_apply_status(void) 702fb4a87a7SPrabhakar Kushwaha { 703fb4a87a7SPrabhakar Kushwaha return mc_aiop_applied; 704fb4a87a7SPrabhakar Kushwaha } 705fb4a87a7SPrabhakar Kushwaha #endif 706fb4a87a7SPrabhakar Kushwaha 707fb4a87a7SPrabhakar Kushwaha int get_dpl_apply_status(void) 708fb4a87a7SPrabhakar Kushwaha { 709fb4a87a7SPrabhakar Kushwaha return mc_dpl_applied; 710fb4a87a7SPrabhakar Kushwaha } 711fb4a87a7SPrabhakar Kushwaha 712fb4a87a7SPrabhakar Kushwaha /** 713fb4a87a7SPrabhakar Kushwaha * Return the MC address of private DRAM block. 714fb4a87a7SPrabhakar Kushwaha */ 715fb4a87a7SPrabhakar Kushwaha u64 mc_get_dram_addr(void) 716fb4a87a7SPrabhakar Kushwaha { 717fb4a87a7SPrabhakar Kushwaha u64 mc_ram_addr; 718fb4a87a7SPrabhakar Kushwaha 719fb4a87a7SPrabhakar Kushwaha /* 720fb4a87a7SPrabhakar Kushwaha * The MC private DRAM block was already carved at the end of DRAM 721fb4a87a7SPrabhakar Kushwaha * by board_init_f() using CONFIG_SYS_MEM_TOP_HIDE: 722fb4a87a7SPrabhakar Kushwaha */ 723fb4a87a7SPrabhakar Kushwaha if (gd->bd->bi_dram[1].start) { 724fb4a87a7SPrabhakar Kushwaha mc_ram_addr = 725fb4a87a7SPrabhakar Kushwaha gd->bd->bi_dram[1].start + gd->bd->bi_dram[1].size; 726fb4a87a7SPrabhakar Kushwaha } else { 727fb4a87a7SPrabhakar Kushwaha mc_ram_addr = 728fb4a87a7SPrabhakar Kushwaha gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size; 729fb4a87a7SPrabhakar Kushwaha } 730fb4a87a7SPrabhakar Kushwaha 731fb4a87a7SPrabhakar Kushwaha return mc_ram_addr; 732fb4a87a7SPrabhakar Kushwaha } 733fb4a87a7SPrabhakar Kushwaha 7347b3bd9a7SJ. German Rivera /** 7357b3bd9a7SJ. German Rivera * Return the actual size of the MC private DRAM block. 7367b3bd9a7SJ. German Rivera */ 7377b3bd9a7SJ. German Rivera unsigned long mc_get_dram_block_size(void) 7387b3bd9a7SJ. German Rivera { 739125e2bc1SJ. German Rivera unsigned long dram_block_size = CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE; 740125e2bc1SJ. German Rivera 741125e2bc1SJ. German Rivera char *dram_block_size_env_var = getenv(MC_MEM_SIZE_ENV_VAR); 742125e2bc1SJ. German Rivera 743125e2bc1SJ. German Rivera if (dram_block_size_env_var) { 744125e2bc1SJ. German Rivera dram_block_size = simple_strtoul(dram_block_size_env_var, NULL, 745125e2bc1SJ. German Rivera 10); 746125e2bc1SJ. German Rivera 747125e2bc1SJ. German Rivera if (dram_block_size < CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE) { 748125e2bc1SJ. German Rivera printf("fsl-mc: WARNING: Invalid value for \'" 749125e2bc1SJ. German Rivera MC_MEM_SIZE_ENV_VAR 750125e2bc1SJ. German Rivera "\' environment variable: %lu\n", 751125e2bc1SJ. German Rivera dram_block_size); 752125e2bc1SJ. German Rivera 753125e2bc1SJ. German Rivera dram_block_size = CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE; 754125e2bc1SJ. German Rivera } 755125e2bc1SJ. German Rivera } 756125e2bc1SJ. German Rivera 757125e2bc1SJ. German Rivera return dram_block_size; 7587b3bd9a7SJ. German Rivera } 759a2a55e51SPrabhakar Kushwaha 7601730a17dSPrabhakar Kushwaha int fsl_mc_ldpaa_init(bd_t *bis) 7611730a17dSPrabhakar Kushwaha { 762c919ab9eSPrabhakar Kushwaha int i; 763c919ab9eSPrabhakar Kushwaha 764c919ab9eSPrabhakar Kushwaha for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) 765c919ab9eSPrabhakar Kushwaha if ((wriop_is_enabled_dpmac(i) == 1) && 766c919ab9eSPrabhakar Kushwaha (wriop_get_phy_address(i) != -1)) 767c919ab9eSPrabhakar Kushwaha ldpaa_eth_init(i, wriop_get_enet_if(i)); 7681730a17dSPrabhakar Kushwaha return 0; 7691730a17dSPrabhakar Kushwaha } 7701730a17dSPrabhakar Kushwaha 7719a696f56SPrabhakar Kushwaha static int dprc_version_check(struct fsl_mc_io *mc_io, uint16_t handle) 7729a696f56SPrabhakar Kushwaha { 7739a696f56SPrabhakar Kushwaha struct dprc_attributes attr; 7749a696f56SPrabhakar Kushwaha int error; 7759a696f56SPrabhakar Kushwaha 7769a696f56SPrabhakar Kushwaha memset(&attr, 0, sizeof(struct dprc_attributes)); 7779a696f56SPrabhakar Kushwaha error = dprc_get_attributes(mc_io, MC_CMD_NO_FLAGS, handle, &attr); 7789a696f56SPrabhakar Kushwaha if (error == 0) { 7799a696f56SPrabhakar Kushwaha if ((attr.version.major != DPRC_VER_MAJOR) || 7809a696f56SPrabhakar Kushwaha (attr.version.minor != DPRC_VER_MINOR)) { 7819a696f56SPrabhakar Kushwaha printf("DPRC version mismatch found %u.%u,", 7829a696f56SPrabhakar Kushwaha attr.version.major, 7839a696f56SPrabhakar Kushwaha attr.version.minor); 7849a696f56SPrabhakar Kushwaha printf("supported version is %u.%u\n", 7859a696f56SPrabhakar Kushwaha DPRC_VER_MAJOR, DPRC_VER_MINOR); 7869a696f56SPrabhakar Kushwaha } 7879a696f56SPrabhakar Kushwaha } 7889a696f56SPrabhakar Kushwaha return error; 7899a696f56SPrabhakar Kushwaha } 7909a696f56SPrabhakar Kushwaha 7911730a17dSPrabhakar Kushwaha static int dpio_init(void) 792a2a55e51SPrabhakar Kushwaha { 793a2a55e51SPrabhakar Kushwaha struct qbman_swp_desc p_des; 794a2a55e51SPrabhakar Kushwaha struct dpio_attr attr; 7951730a17dSPrabhakar Kushwaha struct dpio_cfg dpio_cfg; 796a2a55e51SPrabhakar Kushwaha int err = 0; 797a2a55e51SPrabhakar Kushwaha 798a2a55e51SPrabhakar Kushwaha dflt_dpio = (struct fsl_dpio_obj *)malloc(sizeof(struct fsl_dpio_obj)); 799a2a55e51SPrabhakar Kushwaha if (!dflt_dpio) { 800a2a55e51SPrabhakar Kushwaha printf("No memory: malloc() failed\n"); 8011730a17dSPrabhakar Kushwaha err = -ENOMEM; 8021730a17dSPrabhakar Kushwaha goto err_malloc; 803a2a55e51SPrabhakar Kushwaha } 804a2a55e51SPrabhakar Kushwaha 8051730a17dSPrabhakar Kushwaha dpio_cfg.channel_mode = DPIO_LOCAL_CHANNEL; 8061730a17dSPrabhakar Kushwaha dpio_cfg.num_priorities = 8; 807a2a55e51SPrabhakar Kushwaha 8081730a17dSPrabhakar Kushwaha err = dpio_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpio_cfg, 8091730a17dSPrabhakar Kushwaha &dflt_dpio->dpio_handle); 8101730a17dSPrabhakar Kushwaha if (err < 0) { 8111730a17dSPrabhakar Kushwaha printf("dpio_create() failed: %d\n", err); 8121730a17dSPrabhakar Kushwaha err = -ENODEV; 8131730a17dSPrabhakar Kushwaha goto err_create; 814a2a55e51SPrabhakar Kushwaha } 815a2a55e51SPrabhakar Kushwaha 8161730a17dSPrabhakar Kushwaha memset(&attr, 0, sizeof(struct dpio_attr)); 81787457d11SPrabhakar Kushwaha err = dpio_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, 8181730a17dSPrabhakar Kushwaha dflt_dpio->dpio_handle, &attr); 8191730a17dSPrabhakar Kushwaha if (err < 0) { 8201730a17dSPrabhakar Kushwaha printf("dpio_get_attributes() failed: %d\n", err); 821a2a55e51SPrabhakar Kushwaha goto err_get_attr; 822a2a55e51SPrabhakar Kushwaha } 823a2a55e51SPrabhakar Kushwaha 8249a696f56SPrabhakar Kushwaha if ((attr.version.major != DPIO_VER_MAJOR) || 8259a696f56SPrabhakar Kushwaha (attr.version.minor != DPIO_VER_MINOR)) { 8269a696f56SPrabhakar Kushwaha printf("DPIO version mismatch found %u.%u,", 8279a696f56SPrabhakar Kushwaha attr.version.major, attr.version.minor); 8289a696f56SPrabhakar Kushwaha printf("supported version is %u.%u\n", 8299a696f56SPrabhakar Kushwaha DPIO_VER_MAJOR, DPIO_VER_MINOR); 8309a696f56SPrabhakar Kushwaha } 8319a696f56SPrabhakar Kushwaha 8321730a17dSPrabhakar Kushwaha dflt_dpio->dpio_id = attr.id; 8331730a17dSPrabhakar Kushwaha #ifdef DEBUG 8341730a17dSPrabhakar Kushwaha printf("Init: DPIO id=0x%d\n", dflt_dpio->dpio_id); 8351730a17dSPrabhakar Kushwaha #endif 8361730a17dSPrabhakar Kushwaha err = dpio_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); 8371730a17dSPrabhakar Kushwaha if (err < 0) { 838a2a55e51SPrabhakar Kushwaha printf("dpio_enable() failed %d\n", err); 839a2a55e51SPrabhakar Kushwaha goto err_get_enable; 840a2a55e51SPrabhakar Kushwaha } 8411f1c25c7SPrabhakar Kushwaha debug("ce_offset=0x%llx, ci_offset=0x%llx, portalid=%d, prios=%d\n", 8421f1c25c7SPrabhakar Kushwaha attr.qbman_portal_ce_offset, 8431f1c25c7SPrabhakar Kushwaha attr.qbman_portal_ci_offset, 844a2a55e51SPrabhakar Kushwaha attr.qbman_portal_id, 845a2a55e51SPrabhakar Kushwaha attr.num_priorities); 846a2a55e51SPrabhakar Kushwaha 8471f1c25c7SPrabhakar Kushwaha p_des.cena_bar = (void *)(SOC_QBMAN_PORTALS_BASE_ADDR 8481f1c25c7SPrabhakar Kushwaha + attr.qbman_portal_ce_offset); 8491f1c25c7SPrabhakar Kushwaha p_des.cinh_bar = (void *)(SOC_QBMAN_PORTALS_BASE_ADDR 8501f1c25c7SPrabhakar Kushwaha + attr.qbman_portal_ci_offset); 851a2a55e51SPrabhakar Kushwaha 852a2a55e51SPrabhakar Kushwaha dflt_dpio->sw_portal = qbman_swp_init(&p_des); 853a2a55e51SPrabhakar Kushwaha if (dflt_dpio->sw_portal == NULL) { 854a2a55e51SPrabhakar Kushwaha printf("qbman_swp_init() failed\n"); 855a2a55e51SPrabhakar Kushwaha goto err_get_swp_init; 856a2a55e51SPrabhakar Kushwaha } 857a2a55e51SPrabhakar Kushwaha return 0; 858a2a55e51SPrabhakar Kushwaha 859a2a55e51SPrabhakar Kushwaha err_get_swp_init: 8601730a17dSPrabhakar Kushwaha dpio_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); 861a2a55e51SPrabhakar Kushwaha err_get_enable: 8621730a17dSPrabhakar Kushwaha err_get_attr: 8631730a17dSPrabhakar Kushwaha dpio_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); 8641730a17dSPrabhakar Kushwaha dpio_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); 8651730a17dSPrabhakar Kushwaha err_create: 866cd7b3fbcSPrabhakar Kushwaha free(dflt_dpio); 8671730a17dSPrabhakar Kushwaha err_malloc: 868a2a55e51SPrabhakar Kushwaha return err; 869a2a55e51SPrabhakar Kushwaha } 870a2a55e51SPrabhakar Kushwaha 8711730a17dSPrabhakar Kushwaha static int dpio_exit(void) 872a2a55e51SPrabhakar Kushwaha { 8731730a17dSPrabhakar Kushwaha int err; 8741730a17dSPrabhakar Kushwaha 8751730a17dSPrabhakar Kushwaha err = dpio_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); 8761730a17dSPrabhakar Kushwaha if (err < 0) { 8771730a17dSPrabhakar Kushwaha printf("dpio_disable() failed: %d\n", err); 8781730a17dSPrabhakar Kushwaha goto err; 8791730a17dSPrabhakar Kushwaha } 8801730a17dSPrabhakar Kushwaha 8811730a17dSPrabhakar Kushwaha err = dpio_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); 8821730a17dSPrabhakar Kushwaha if (err < 0) { 8831730a17dSPrabhakar Kushwaha printf("dpio_destroy() failed: %d\n", err); 8841730a17dSPrabhakar Kushwaha goto err; 8851730a17dSPrabhakar Kushwaha } 8861730a17dSPrabhakar Kushwaha 8871730a17dSPrabhakar Kushwaha #ifdef DEBUG 8881730a17dSPrabhakar Kushwaha printf("Exit: DPIO id=0x%d\n", dflt_dpio->dpio_id); 8891730a17dSPrabhakar Kushwaha #endif 8901730a17dSPrabhakar Kushwaha 8911730a17dSPrabhakar Kushwaha if (dflt_dpio) 8921730a17dSPrabhakar Kushwaha free(dflt_dpio); 8931730a17dSPrabhakar Kushwaha 8941730a17dSPrabhakar Kushwaha return 0; 8951730a17dSPrabhakar Kushwaha err: 8961730a17dSPrabhakar Kushwaha return err; 8971730a17dSPrabhakar Kushwaha } 8981730a17dSPrabhakar Kushwaha 8991730a17dSPrabhakar Kushwaha static int dprc_init(void) 9001730a17dSPrabhakar Kushwaha { 9011730a17dSPrabhakar Kushwaha int err, child_portal_id, container_id; 9021730a17dSPrabhakar Kushwaha struct dprc_cfg cfg; 9031730a17dSPrabhakar Kushwaha uint64_t mc_portal_offset; 9041730a17dSPrabhakar Kushwaha 9051730a17dSPrabhakar Kushwaha /* Open root container */ 9061730a17dSPrabhakar Kushwaha err = dprc_get_container_id(root_mc_io, MC_CMD_NO_FLAGS, &container_id); 9071730a17dSPrabhakar Kushwaha if (err < 0) { 9081730a17dSPrabhakar Kushwaha printf("dprc_get_container_id(): Root failed: %d\n", err); 9091730a17dSPrabhakar Kushwaha goto err_root_container_id; 9101730a17dSPrabhakar Kushwaha } 9111730a17dSPrabhakar Kushwaha 9121730a17dSPrabhakar Kushwaha #ifdef DEBUG 9131730a17dSPrabhakar Kushwaha printf("Root container id = %d\n", container_id); 9141730a17dSPrabhakar Kushwaha #endif 9151730a17dSPrabhakar Kushwaha err = dprc_open(root_mc_io, MC_CMD_NO_FLAGS, container_id, 9161730a17dSPrabhakar Kushwaha &root_dprc_handle); 9171730a17dSPrabhakar Kushwaha if (err < 0) { 9181730a17dSPrabhakar Kushwaha printf("dprc_open(): Root Container failed: %d\n", err); 9191730a17dSPrabhakar Kushwaha goto err_root_open; 9201730a17dSPrabhakar Kushwaha } 9211730a17dSPrabhakar Kushwaha 9221730a17dSPrabhakar Kushwaha if (!root_dprc_handle) { 9231730a17dSPrabhakar Kushwaha printf("dprc_open(): Root Container Handle is not valid\n"); 9241730a17dSPrabhakar Kushwaha goto err_root_open; 9251730a17dSPrabhakar Kushwaha } 9261730a17dSPrabhakar Kushwaha 9279a696f56SPrabhakar Kushwaha err = dprc_version_check(root_mc_io, root_dprc_handle); 9289a696f56SPrabhakar Kushwaha if (err < 0) { 9299a696f56SPrabhakar Kushwaha printf("dprc_version_check() failed: %d\n", err); 9309a696f56SPrabhakar Kushwaha goto err_root_open; 9319a696f56SPrabhakar Kushwaha } 9329a696f56SPrabhakar Kushwaha 9335373b204SPrabhakar Kushwaha memset(&cfg, 0, sizeof(struct dprc_cfg)); 9341730a17dSPrabhakar Kushwaha cfg.options = DPRC_CFG_OPT_TOPOLOGY_CHANGES_ALLOWED | 9351730a17dSPrabhakar Kushwaha DPRC_CFG_OPT_OBJ_CREATE_ALLOWED | 9361730a17dSPrabhakar Kushwaha DPRC_CFG_OPT_ALLOC_ALLOWED; 9371730a17dSPrabhakar Kushwaha cfg.icid = DPRC_GET_ICID_FROM_POOL; 938335b1936SPrabhakar Kushwaha cfg.portal_id = DPRC_GET_PORTAL_ID_FROM_POOL; 9391730a17dSPrabhakar Kushwaha err = dprc_create_container(root_mc_io, MC_CMD_NO_FLAGS, 9401730a17dSPrabhakar Kushwaha root_dprc_handle, 9411730a17dSPrabhakar Kushwaha &cfg, 9421730a17dSPrabhakar Kushwaha &child_dprc_id, 9431730a17dSPrabhakar Kushwaha &mc_portal_offset); 9441730a17dSPrabhakar Kushwaha if (err < 0) { 9451730a17dSPrabhakar Kushwaha printf("dprc_create_container() failed: %d\n", err); 9461730a17dSPrabhakar Kushwaha goto err_create; 9471730a17dSPrabhakar Kushwaha } 9481730a17dSPrabhakar Kushwaha 9491730a17dSPrabhakar Kushwaha dflt_mc_io = (struct fsl_mc_io *)malloc(sizeof(struct fsl_mc_io)); 9501730a17dSPrabhakar Kushwaha if (!dflt_mc_io) { 9511730a17dSPrabhakar Kushwaha err = -ENOMEM; 9521730a17dSPrabhakar Kushwaha printf(" No memory: malloc() failed\n"); 9531730a17dSPrabhakar Kushwaha goto err_malloc; 9541730a17dSPrabhakar Kushwaha } 9551730a17dSPrabhakar Kushwaha 9561730a17dSPrabhakar Kushwaha child_portal_id = MC_PORTAL_OFFSET_TO_PORTAL_ID(mc_portal_offset); 9571730a17dSPrabhakar Kushwaha dflt_mc_io->mmio_regs = SOC_MC_PORTAL_ADDR(child_portal_id); 9581730a17dSPrabhakar Kushwaha #ifdef DEBUG 9591730a17dSPrabhakar Kushwaha printf("MC portal of child DPRC container: %d, physical addr %p)\n", 9601730a17dSPrabhakar Kushwaha child_dprc_id, dflt_mc_io->mmio_regs); 9611730a17dSPrabhakar Kushwaha #endif 9621730a17dSPrabhakar Kushwaha 9631730a17dSPrabhakar Kushwaha err = dprc_open(dflt_mc_io, MC_CMD_NO_FLAGS, child_dprc_id, 9641730a17dSPrabhakar Kushwaha &dflt_dprc_handle); 9651730a17dSPrabhakar Kushwaha if (err < 0) { 9661730a17dSPrabhakar Kushwaha printf("dprc_open(): Child container failed: %d\n", err); 9671730a17dSPrabhakar Kushwaha goto err_child_open; 9681730a17dSPrabhakar Kushwaha } 9691730a17dSPrabhakar Kushwaha 9701730a17dSPrabhakar Kushwaha if (!dflt_dprc_handle) { 9711730a17dSPrabhakar Kushwaha printf("dprc_open(): Child container Handle is not valid\n"); 9721730a17dSPrabhakar Kushwaha goto err_child_open; 9731730a17dSPrabhakar Kushwaha } 9741730a17dSPrabhakar Kushwaha 9751730a17dSPrabhakar Kushwaha return 0; 9761730a17dSPrabhakar Kushwaha err_child_open: 9771730a17dSPrabhakar Kushwaha free(dflt_mc_io); 9781730a17dSPrabhakar Kushwaha err_malloc: 9791730a17dSPrabhakar Kushwaha dprc_destroy_container(root_mc_io, MC_CMD_NO_FLAGS, 9801730a17dSPrabhakar Kushwaha root_dprc_handle, child_dprc_id); 9811730a17dSPrabhakar Kushwaha err_create: 9821730a17dSPrabhakar Kushwaha dprc_close(root_mc_io, MC_CMD_NO_FLAGS, root_dprc_handle); 9831730a17dSPrabhakar Kushwaha err_root_open: 9841730a17dSPrabhakar Kushwaha err_root_container_id: 9851730a17dSPrabhakar Kushwaha return err; 9861730a17dSPrabhakar Kushwaha } 9871730a17dSPrabhakar Kushwaha 9881730a17dSPrabhakar Kushwaha static int dprc_exit(void) 9891730a17dSPrabhakar Kushwaha { 9901730a17dSPrabhakar Kushwaha int err; 9911730a17dSPrabhakar Kushwaha 9921730a17dSPrabhakar Kushwaha err = dprc_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dprc_handle); 9931730a17dSPrabhakar Kushwaha if (err < 0) { 9941730a17dSPrabhakar Kushwaha printf("dprc_close(): Child failed: %d\n", err); 9951730a17dSPrabhakar Kushwaha goto err; 9961730a17dSPrabhakar Kushwaha } 9971730a17dSPrabhakar Kushwaha 9981730a17dSPrabhakar Kushwaha err = dprc_destroy_container(root_mc_io, MC_CMD_NO_FLAGS, 9991730a17dSPrabhakar Kushwaha root_dprc_handle, child_dprc_id); 10001730a17dSPrabhakar Kushwaha if (err < 0) { 10011730a17dSPrabhakar Kushwaha printf("dprc_destroy_container() failed: %d\n", err); 10021730a17dSPrabhakar Kushwaha goto err; 10031730a17dSPrabhakar Kushwaha } 10041730a17dSPrabhakar Kushwaha 10051730a17dSPrabhakar Kushwaha err = dprc_close(root_mc_io, MC_CMD_NO_FLAGS, root_dprc_handle); 10061730a17dSPrabhakar Kushwaha if (err < 0) { 10071730a17dSPrabhakar Kushwaha printf("dprc_close(): Root failed: %d\n", err); 10081730a17dSPrabhakar Kushwaha goto err; 10091730a17dSPrabhakar Kushwaha } 10101730a17dSPrabhakar Kushwaha 10111730a17dSPrabhakar Kushwaha if (dflt_mc_io) 10121730a17dSPrabhakar Kushwaha free(dflt_mc_io); 10131730a17dSPrabhakar Kushwaha 10141730a17dSPrabhakar Kushwaha if (root_mc_io) 10151730a17dSPrabhakar Kushwaha free(root_mc_io); 10161730a17dSPrabhakar Kushwaha 10171730a17dSPrabhakar Kushwaha return 0; 10181730a17dSPrabhakar Kushwaha 10191730a17dSPrabhakar Kushwaha err: 10201730a17dSPrabhakar Kushwaha return err; 10211730a17dSPrabhakar Kushwaha } 10221730a17dSPrabhakar Kushwaha 10231730a17dSPrabhakar Kushwaha static int dpbp_init(void) 10241730a17dSPrabhakar Kushwaha { 10251730a17dSPrabhakar Kushwaha int err; 10261730a17dSPrabhakar Kushwaha struct dpbp_attr dpbp_attr; 10271730a17dSPrabhakar Kushwaha struct dpbp_cfg dpbp_cfg; 10281730a17dSPrabhakar Kushwaha 1029a2a55e51SPrabhakar Kushwaha dflt_dpbp = (struct fsl_dpbp_obj *)malloc(sizeof(struct fsl_dpbp_obj)); 1030a2a55e51SPrabhakar Kushwaha if (!dflt_dpbp) { 1031a2a55e51SPrabhakar Kushwaha printf("No memory: malloc() failed\n"); 10321730a17dSPrabhakar Kushwaha err = -ENOMEM; 10331730a17dSPrabhakar Kushwaha goto err_malloc; 1034a2a55e51SPrabhakar Kushwaha } 10351730a17dSPrabhakar Kushwaha 10361730a17dSPrabhakar Kushwaha dpbp_cfg.options = 512; 10371730a17dSPrabhakar Kushwaha 10381730a17dSPrabhakar Kushwaha err = dpbp_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpbp_cfg, 10391730a17dSPrabhakar Kushwaha &dflt_dpbp->dpbp_handle); 10401730a17dSPrabhakar Kushwaha 10411730a17dSPrabhakar Kushwaha if (err < 0) { 10421730a17dSPrabhakar Kushwaha err = -ENODEV; 10431730a17dSPrabhakar Kushwaha printf("dpbp_create() failed: %d\n", err); 10441730a17dSPrabhakar Kushwaha goto err_create; 10451730a17dSPrabhakar Kushwaha } 10461730a17dSPrabhakar Kushwaha 10471730a17dSPrabhakar Kushwaha memset(&dpbp_attr, 0, sizeof(struct dpbp_attr)); 10481730a17dSPrabhakar Kushwaha err = dpbp_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, 10491730a17dSPrabhakar Kushwaha dflt_dpbp->dpbp_handle, 10501730a17dSPrabhakar Kushwaha &dpbp_attr); 10511730a17dSPrabhakar Kushwaha if (err < 0) { 10521730a17dSPrabhakar Kushwaha printf("dpbp_get_attributes() failed: %d\n", err); 10531730a17dSPrabhakar Kushwaha goto err_get_attr; 10541730a17dSPrabhakar Kushwaha } 10551730a17dSPrabhakar Kushwaha 10569a696f56SPrabhakar Kushwaha if ((dpbp_attr.version.major != DPBP_VER_MAJOR) || 10579a696f56SPrabhakar Kushwaha (dpbp_attr.version.minor != DPBP_VER_MINOR)) { 10589a696f56SPrabhakar Kushwaha printf("DPBP version mismatch found %u.%u,", 10599a696f56SPrabhakar Kushwaha dpbp_attr.version.major, dpbp_attr.version.minor); 10609a696f56SPrabhakar Kushwaha printf("supported version is %u.%u\n", 10619a696f56SPrabhakar Kushwaha DPBP_VER_MAJOR, DPBP_VER_MINOR); 10629a696f56SPrabhakar Kushwaha } 10639a696f56SPrabhakar Kushwaha 10641730a17dSPrabhakar Kushwaha dflt_dpbp->dpbp_attr.id = dpbp_attr.id; 10651730a17dSPrabhakar Kushwaha #ifdef DEBUG 10661730a17dSPrabhakar Kushwaha printf("Init: DPBP id=0x%d\n", dflt_dpbp->dpbp_attr.id); 10671730a17dSPrabhakar Kushwaha #endif 10681730a17dSPrabhakar Kushwaha 10691730a17dSPrabhakar Kushwaha err = dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 10701730a17dSPrabhakar Kushwaha if (err < 0) { 10711730a17dSPrabhakar Kushwaha printf("dpbp_close() failed: %d\n", err); 10721730a17dSPrabhakar Kushwaha goto err_close; 10731730a17dSPrabhakar Kushwaha } 1074a2a55e51SPrabhakar Kushwaha 1075a2a55e51SPrabhakar Kushwaha return 0; 10761730a17dSPrabhakar Kushwaha 10771730a17dSPrabhakar Kushwaha err_close: 10781730a17dSPrabhakar Kushwaha free(dflt_dpbp); 10791730a17dSPrabhakar Kushwaha err_get_attr: 10801730a17dSPrabhakar Kushwaha dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 10811730a17dSPrabhakar Kushwaha dpbp_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 10821730a17dSPrabhakar Kushwaha err_create: 10831730a17dSPrabhakar Kushwaha err_malloc: 10841730a17dSPrabhakar Kushwaha return err; 1085a2a55e51SPrabhakar Kushwaha } 1086a2a55e51SPrabhakar Kushwaha 10871730a17dSPrabhakar Kushwaha static int dpbp_exit(void) 1088a2a55e51SPrabhakar Kushwaha { 10891730a17dSPrabhakar Kushwaha int err; 10901730a17dSPrabhakar Kushwaha 10911730a17dSPrabhakar Kushwaha err = dpbp_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_attr.id, 10921730a17dSPrabhakar Kushwaha &dflt_dpbp->dpbp_handle); 10931730a17dSPrabhakar Kushwaha if (err < 0) { 10941730a17dSPrabhakar Kushwaha printf("dpbp_open() failed: %d\n", err); 10951730a17dSPrabhakar Kushwaha goto err; 10961730a17dSPrabhakar Kushwaha } 10971730a17dSPrabhakar Kushwaha 10981730a17dSPrabhakar Kushwaha err = dpbp_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, 10991730a17dSPrabhakar Kushwaha dflt_dpbp->dpbp_handle); 11001730a17dSPrabhakar Kushwaha if (err < 0) { 11011730a17dSPrabhakar Kushwaha printf("dpbp_destroy() failed: %d\n", err); 11021730a17dSPrabhakar Kushwaha goto err; 11031730a17dSPrabhakar Kushwaha } 11041730a17dSPrabhakar Kushwaha 11051730a17dSPrabhakar Kushwaha #ifdef DEBUG 11061730a17dSPrabhakar Kushwaha printf("Exit: DPBP id=0x%d\n", dflt_dpbp->dpbp_attr.id); 11071730a17dSPrabhakar Kushwaha #endif 11081730a17dSPrabhakar Kushwaha 11091730a17dSPrabhakar Kushwaha if (dflt_dpbp) 11101730a17dSPrabhakar Kushwaha free(dflt_dpbp); 11111730a17dSPrabhakar Kushwaha return 0; 11121730a17dSPrabhakar Kushwaha 11131730a17dSPrabhakar Kushwaha err: 11141730a17dSPrabhakar Kushwaha return err; 11151730a17dSPrabhakar Kushwaha } 11161730a17dSPrabhakar Kushwaha 11171730a17dSPrabhakar Kushwaha static int dpni_init(void) 11181730a17dSPrabhakar Kushwaha { 11191730a17dSPrabhakar Kushwaha int err; 11201730a17dSPrabhakar Kushwaha struct dpni_attr dpni_attr; 1121879a59acSPrabhakar Kushwaha uint8_t ext_cfg_buf[256] = {0}; 1122879a59acSPrabhakar Kushwaha struct dpni_extended_cfg dpni_extended_cfg; 11231730a17dSPrabhakar Kushwaha struct dpni_cfg dpni_cfg; 11241730a17dSPrabhakar Kushwaha 11251730a17dSPrabhakar Kushwaha dflt_dpni = (struct fsl_dpni_obj *)malloc(sizeof(struct fsl_dpni_obj)); 11261730a17dSPrabhakar Kushwaha if (!dflt_dpni) { 11271730a17dSPrabhakar Kushwaha printf("No memory: malloc() failed\n"); 11281730a17dSPrabhakar Kushwaha err = -ENOMEM; 11291730a17dSPrabhakar Kushwaha goto err_malloc; 11301730a17dSPrabhakar Kushwaha } 11311730a17dSPrabhakar Kushwaha 1132879a59acSPrabhakar Kushwaha memset(&dpni_extended_cfg, 0, sizeof(dpni_extended_cfg)); 1133879a59acSPrabhakar Kushwaha err = dpni_prepare_extended_cfg(&dpni_extended_cfg, &ext_cfg_buf[0]); 1134879a59acSPrabhakar Kushwaha if (err < 0) { 1135879a59acSPrabhakar Kushwaha err = -ENODEV; 1136879a59acSPrabhakar Kushwaha printf("dpni_prepare_extended_cfg() failed: %d\n", err); 1137879a59acSPrabhakar Kushwaha goto err_prepare_extended_cfg; 1138879a59acSPrabhakar Kushwaha } 1139879a59acSPrabhakar Kushwaha 11401730a17dSPrabhakar Kushwaha memset(&dpni_cfg, 0, sizeof(dpni_cfg)); 11411730a17dSPrabhakar Kushwaha dpni_cfg.adv.options = DPNI_OPT_UNICAST_FILTER | 11421730a17dSPrabhakar Kushwaha DPNI_OPT_MULTICAST_FILTER; 11431730a17dSPrabhakar Kushwaha 1144879a59acSPrabhakar Kushwaha dpni_cfg.adv.ext_cfg_iova = (uint64_t)&ext_cfg_buf[0]; 11451730a17dSPrabhakar Kushwaha err = dpni_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpni_cfg, 11461730a17dSPrabhakar Kushwaha &dflt_dpni->dpni_handle); 11471730a17dSPrabhakar Kushwaha 11481730a17dSPrabhakar Kushwaha if (err < 0) { 11491730a17dSPrabhakar Kushwaha err = -ENODEV; 11501730a17dSPrabhakar Kushwaha printf("dpni_create() failed: %d\n", err); 11511730a17dSPrabhakar Kushwaha goto err_create; 11521730a17dSPrabhakar Kushwaha } 11531730a17dSPrabhakar Kushwaha 11541730a17dSPrabhakar Kushwaha memset(&dpni_attr, 0, sizeof(struct dpni_attr)); 11551730a17dSPrabhakar Kushwaha err = dpni_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, 11561730a17dSPrabhakar Kushwaha dflt_dpni->dpni_handle, 11571730a17dSPrabhakar Kushwaha &dpni_attr); 11581730a17dSPrabhakar Kushwaha if (err < 0) { 11591730a17dSPrabhakar Kushwaha printf("dpni_get_attributes() failed: %d\n", err); 11601730a17dSPrabhakar Kushwaha goto err_get_attr; 11611730a17dSPrabhakar Kushwaha } 11621730a17dSPrabhakar Kushwaha 11639a696f56SPrabhakar Kushwaha if ((dpni_attr.version.major != DPNI_VER_MAJOR) || 11649a696f56SPrabhakar Kushwaha (dpni_attr.version.minor != DPNI_VER_MINOR)) { 11659a696f56SPrabhakar Kushwaha printf("DPNI version mismatch found %u.%u,", 11669a696f56SPrabhakar Kushwaha dpni_attr.version.major, dpni_attr.version.minor); 11679a696f56SPrabhakar Kushwaha printf("supported version is %u.%u\n", 11689a696f56SPrabhakar Kushwaha DPNI_VER_MAJOR, DPNI_VER_MINOR); 11699a696f56SPrabhakar Kushwaha } 11709a696f56SPrabhakar Kushwaha 11711730a17dSPrabhakar Kushwaha dflt_dpni->dpni_id = dpni_attr.id; 11721730a17dSPrabhakar Kushwaha #ifdef DEBUG 11731730a17dSPrabhakar Kushwaha printf("Init: DPNI id=0x%d\n", dflt_dpni->dpni_id); 11741730a17dSPrabhakar Kushwaha #endif 11751730a17dSPrabhakar Kushwaha 11761730a17dSPrabhakar Kushwaha err = dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 11771730a17dSPrabhakar Kushwaha if (err < 0) { 11781730a17dSPrabhakar Kushwaha printf("dpni_close() failed: %d\n", err); 11791730a17dSPrabhakar Kushwaha goto err_close; 11801730a17dSPrabhakar Kushwaha } 1181a2a55e51SPrabhakar Kushwaha 1182fb4a87a7SPrabhakar Kushwaha return 0; 11831730a17dSPrabhakar Kushwaha 11841730a17dSPrabhakar Kushwaha err_close: 11851730a17dSPrabhakar Kushwaha err_get_attr: 11861730a17dSPrabhakar Kushwaha dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 11871730a17dSPrabhakar Kushwaha dpni_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 11881730a17dSPrabhakar Kushwaha err_create: 1189879a59acSPrabhakar Kushwaha err_prepare_extended_cfg: 1190879a59acSPrabhakar Kushwaha free(dflt_dpni); 11911730a17dSPrabhakar Kushwaha err_malloc: 11921730a17dSPrabhakar Kushwaha return err; 1193a2a55e51SPrabhakar Kushwaha } 1194a2a55e51SPrabhakar Kushwaha 11951730a17dSPrabhakar Kushwaha static int dpni_exit(void) 1196a2a55e51SPrabhakar Kushwaha { 11971730a17dSPrabhakar Kushwaha int err; 11981730a17dSPrabhakar Kushwaha 11991730a17dSPrabhakar Kushwaha err = dpni_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_id, 12001730a17dSPrabhakar Kushwaha &dflt_dpni->dpni_handle); 12011730a17dSPrabhakar Kushwaha if (err < 0) { 12021730a17dSPrabhakar Kushwaha printf("dpni_open() failed: %d\n", err); 12031730a17dSPrabhakar Kushwaha goto err; 12041730a17dSPrabhakar Kushwaha } 12051730a17dSPrabhakar Kushwaha 12061730a17dSPrabhakar Kushwaha err = dpni_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, 12071730a17dSPrabhakar Kushwaha dflt_dpni->dpni_handle); 12081730a17dSPrabhakar Kushwaha if (err < 0) { 12091730a17dSPrabhakar Kushwaha printf("dpni_destroy() failed: %d\n", err); 12101730a17dSPrabhakar Kushwaha goto err; 12111730a17dSPrabhakar Kushwaha } 12121730a17dSPrabhakar Kushwaha 12131730a17dSPrabhakar Kushwaha #ifdef DEBUG 12141730a17dSPrabhakar Kushwaha printf("Exit: DPNI id=0x%d\n", dflt_dpni->dpni_id); 12151730a17dSPrabhakar Kushwaha #endif 12161730a17dSPrabhakar Kushwaha 12171730a17dSPrabhakar Kushwaha if (dflt_dpni) 12181730a17dSPrabhakar Kushwaha free(dflt_dpni); 12191730a17dSPrabhakar Kushwaha return 0; 12201730a17dSPrabhakar Kushwaha 12211730a17dSPrabhakar Kushwaha err: 12221730a17dSPrabhakar Kushwaha return err; 12231730a17dSPrabhakar Kushwaha } 12241730a17dSPrabhakar Kushwaha 12251730a17dSPrabhakar Kushwaha static int mc_init_object(void) 12261730a17dSPrabhakar Kushwaha { 12271730a17dSPrabhakar Kushwaha int err = 0; 12281730a17dSPrabhakar Kushwaha 12291730a17dSPrabhakar Kushwaha err = dprc_init(); 12301730a17dSPrabhakar Kushwaha if (err < 0) { 12311730a17dSPrabhakar Kushwaha printf("dprc_init() failed: %d\n", err); 12321730a17dSPrabhakar Kushwaha goto err; 12331730a17dSPrabhakar Kushwaha } 12341730a17dSPrabhakar Kushwaha 12351730a17dSPrabhakar Kushwaha err = dpbp_init(); 12361730a17dSPrabhakar Kushwaha if (err < 0) { 12371730a17dSPrabhakar Kushwaha printf("dpbp_init() failed: %d\n", err); 12381730a17dSPrabhakar Kushwaha goto err; 12391730a17dSPrabhakar Kushwaha } 12401730a17dSPrabhakar Kushwaha 12411730a17dSPrabhakar Kushwaha err = dpio_init(); 12421730a17dSPrabhakar Kushwaha if (err < 0) { 12431730a17dSPrabhakar Kushwaha printf("dpio_init() failed: %d\n", err); 12441730a17dSPrabhakar Kushwaha goto err; 12451730a17dSPrabhakar Kushwaha } 12461730a17dSPrabhakar Kushwaha 12471730a17dSPrabhakar Kushwaha err = dpni_init(); 12481730a17dSPrabhakar Kushwaha if (err < 0) { 12491730a17dSPrabhakar Kushwaha printf("dpni_init() failed: %d\n", err); 12501730a17dSPrabhakar Kushwaha goto err; 12511730a17dSPrabhakar Kushwaha } 12521730a17dSPrabhakar Kushwaha 12531730a17dSPrabhakar Kushwaha return 0; 12541730a17dSPrabhakar Kushwaha err: 12551730a17dSPrabhakar Kushwaha return err; 12561730a17dSPrabhakar Kushwaha } 12571730a17dSPrabhakar Kushwaha 12581730a17dSPrabhakar Kushwaha int fsl_mc_ldpaa_exit(bd_t *bd) 12591730a17dSPrabhakar Kushwaha { 12601730a17dSPrabhakar Kushwaha int err = 0; 12611730a17dSPrabhakar Kushwaha 1262b7b8410aSAlexander Graf if (bd && mc_lazy_dpl_addr && !fsl_mc_ldpaa_exit(NULL)) { 1263b7b8410aSAlexander Graf mc_apply_dpl(mc_lazy_dpl_addr); 1264b7b8410aSAlexander Graf mc_lazy_dpl_addr = 0; 1265b7b8410aSAlexander Graf } 1266b7b8410aSAlexander Graf 12676dedceddSPrabhakar Kushwaha /* MC is not loaded intentionally, So return success. */ 12686dedceddSPrabhakar Kushwaha if (bd && get_mc_boot_status() != 0) 12691730a17dSPrabhakar Kushwaha return 0; 12701730a17dSPrabhakar Kushwaha 12711730a17dSPrabhakar Kushwaha if (bd && !get_mc_boot_status() && get_dpl_apply_status() == -1) { 12721730a17dSPrabhakar Kushwaha printf("ERROR: fsl-mc: DPL is not applied\n"); 12731730a17dSPrabhakar Kushwaha err = -ENODEV; 12741730a17dSPrabhakar Kushwaha return err; 12751730a17dSPrabhakar Kushwaha } 12761730a17dSPrabhakar Kushwaha 12771730a17dSPrabhakar Kushwaha if (bd && !get_mc_boot_status() && !get_dpl_apply_status()) 12781730a17dSPrabhakar Kushwaha return err; 12791730a17dSPrabhakar Kushwaha 12801730a17dSPrabhakar Kushwaha err = dpbp_exit(); 12811730a17dSPrabhakar Kushwaha if (err < 0) { 1282a2a4dc56SPrabhakar Kushwaha printf("dpbp_exit() failed: %d\n", err); 12831730a17dSPrabhakar Kushwaha goto err; 12841730a17dSPrabhakar Kushwaha } 12851730a17dSPrabhakar Kushwaha 12861730a17dSPrabhakar Kushwaha err = dpio_exit(); 12871730a17dSPrabhakar Kushwaha if (err < 0) { 12881730a17dSPrabhakar Kushwaha printf("dpio_exit() failed: %d\n", err); 12891730a17dSPrabhakar Kushwaha goto err; 12901730a17dSPrabhakar Kushwaha } 12911730a17dSPrabhakar Kushwaha 12921730a17dSPrabhakar Kushwaha err = dpni_exit(); 12931730a17dSPrabhakar Kushwaha if (err < 0) { 12941730a17dSPrabhakar Kushwaha printf("dpni_exit() failed: %d\n", err); 12951730a17dSPrabhakar Kushwaha goto err; 12961730a17dSPrabhakar Kushwaha } 12971730a17dSPrabhakar Kushwaha 12981730a17dSPrabhakar Kushwaha err = dprc_exit(); 12991730a17dSPrabhakar Kushwaha if (err < 0) { 13001730a17dSPrabhakar Kushwaha printf("dprc_exit() failed: %d\n", err); 13011730a17dSPrabhakar Kushwaha goto err; 13021730a17dSPrabhakar Kushwaha } 13031730a17dSPrabhakar Kushwaha 13041730a17dSPrabhakar Kushwaha return 0; 13051730a17dSPrabhakar Kushwaha err: 13061730a17dSPrabhakar Kushwaha return err; 1307fb4a87a7SPrabhakar Kushwaha } 1308fb4a87a7SPrabhakar Kushwaha 1309fb4a87a7SPrabhakar Kushwaha static int do_fsl_mc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 1310fb4a87a7SPrabhakar Kushwaha { 1311fb4a87a7SPrabhakar Kushwaha int err = 0; 1312fb4a87a7SPrabhakar Kushwaha if (argc < 3) 1313fb4a87a7SPrabhakar Kushwaha goto usage; 1314fb4a87a7SPrabhakar Kushwaha 1315fb4a87a7SPrabhakar Kushwaha switch (argv[1][0]) { 1316fb4a87a7SPrabhakar Kushwaha case 's': { 1317fb4a87a7SPrabhakar Kushwaha char sub_cmd; 131844937214SPrabhakar Kushwaha u64 mc_fw_addr, mc_dpc_addr; 131944937214SPrabhakar Kushwaha #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET 132044937214SPrabhakar Kushwaha u64 aiop_fw_addr; 132144937214SPrabhakar Kushwaha #endif 1322fb4a87a7SPrabhakar Kushwaha 1323fb4a87a7SPrabhakar Kushwaha sub_cmd = argv[2][0]; 1324fb4a87a7SPrabhakar Kushwaha switch (sub_cmd) { 1325fb4a87a7SPrabhakar Kushwaha case 'm': 1326fb4a87a7SPrabhakar Kushwaha if (argc < 5) 1327fb4a87a7SPrabhakar Kushwaha goto usage; 1328a2a55e51SPrabhakar Kushwaha 1329125e2bc1SJ. German Rivera if (get_mc_boot_status() == 0) { 1330fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: MC is already booted"); 1331fb4a87a7SPrabhakar Kushwaha printf("\n"); 1332fb4a87a7SPrabhakar Kushwaha return err; 1333a2a55e51SPrabhakar Kushwaha } 1334fb4a87a7SPrabhakar Kushwaha mc_fw_addr = simple_strtoull(argv[3], NULL, 16); 1335fb4a87a7SPrabhakar Kushwaha mc_dpc_addr = simple_strtoull(argv[4], NULL, 1336fb4a87a7SPrabhakar Kushwaha 16); 13371730a17dSPrabhakar Kushwaha 13381730a17dSPrabhakar Kushwaha if (!mc_init(mc_fw_addr, mc_dpc_addr)) 13391730a17dSPrabhakar Kushwaha err = mc_init_object(); 1340fb4a87a7SPrabhakar Kushwaha break; 1341fb4a87a7SPrabhakar Kushwaha 1342fb4a87a7SPrabhakar Kushwaha #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET 1343fb4a87a7SPrabhakar Kushwaha case 'a': 1344fb4a87a7SPrabhakar Kushwaha if (argc < 4) 1345fb4a87a7SPrabhakar Kushwaha goto usage; 1346fb4a87a7SPrabhakar Kushwaha if (get_aiop_apply_status() == 0) { 1347fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: AIOP FW is already"); 1348fb4a87a7SPrabhakar Kushwaha printf(" applied\n"); 1349fb4a87a7SPrabhakar Kushwaha return err; 1350a2a55e51SPrabhakar Kushwaha } 1351a2a55e51SPrabhakar Kushwaha 1352fb4a87a7SPrabhakar Kushwaha aiop_fw_addr = simple_strtoull(argv[3], NULL, 1353fb4a87a7SPrabhakar Kushwaha 16); 1354fb4a87a7SPrabhakar Kushwaha 13553c1d218aSYork Sun /* if SoC doesn't have AIOP, err = -ENODEV */ 1356fb4a87a7SPrabhakar Kushwaha err = load_mc_aiop_img(aiop_fw_addr); 1357fb4a87a7SPrabhakar Kushwaha if (!err) 1358fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: AIOP FW applied\n"); 1359fb4a87a7SPrabhakar Kushwaha break; 1360fb4a87a7SPrabhakar Kushwaha #endif 1361fb4a87a7SPrabhakar Kushwaha default: 1362fb4a87a7SPrabhakar Kushwaha printf("Invalid option: %s\n", argv[2]); 1363fb4a87a7SPrabhakar Kushwaha goto usage; 1364fb4a87a7SPrabhakar Kushwaha 1365fb4a87a7SPrabhakar Kushwaha break; 1366fb4a87a7SPrabhakar Kushwaha } 1367fb4a87a7SPrabhakar Kushwaha } 1368fb4a87a7SPrabhakar Kushwaha break; 1369fb4a87a7SPrabhakar Kushwaha 1370b7b8410aSAlexander Graf case 'l': 1371fb4a87a7SPrabhakar Kushwaha case 'a': { 1372fb4a87a7SPrabhakar Kushwaha u64 mc_dpl_addr; 1373fb4a87a7SPrabhakar Kushwaha 1374fb4a87a7SPrabhakar Kushwaha if (argc < 4) 1375fb4a87a7SPrabhakar Kushwaha goto usage; 1376fb4a87a7SPrabhakar Kushwaha 1377fb4a87a7SPrabhakar Kushwaha if (get_dpl_apply_status() == 0) { 1378fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: DPL already applied\n"); 1379fb4a87a7SPrabhakar Kushwaha return err; 1380125e2bc1SJ. German Rivera } 1381125e2bc1SJ. German Rivera 1382fb4a87a7SPrabhakar Kushwaha mc_dpl_addr = simple_strtoull(argv[3], NULL, 1383fb4a87a7SPrabhakar Kushwaha 16); 13841730a17dSPrabhakar Kushwaha 1385fb4a87a7SPrabhakar Kushwaha if (get_mc_boot_status() != 0) { 1386fb4a87a7SPrabhakar Kushwaha printf("fsl-mc: Deploying data path layout .."); 1387fb4a87a7SPrabhakar Kushwaha printf("ERROR (MC is not booted)\n"); 1388fb4a87a7SPrabhakar Kushwaha return -ENODEV; 1389a2a55e51SPrabhakar Kushwaha } 13901730a17dSPrabhakar Kushwaha 1391b7b8410aSAlexander Graf if (argv[1][0] == 'l') { 1392b7b8410aSAlexander Graf /* 1393b7b8410aSAlexander Graf * We will do the actual dpaa exit and dpl apply 1394b7b8410aSAlexander Graf * later from announce_and_cleanup(). 1395b7b8410aSAlexander Graf */ 1396b7b8410aSAlexander Graf mc_lazy_dpl_addr = mc_dpl_addr; 1397b7b8410aSAlexander Graf } else { 1398b7b8410aSAlexander Graf /* The user wants it applied now */ 13991730a17dSPrabhakar Kushwaha if (!fsl_mc_ldpaa_exit(NULL)) 1400fb4a87a7SPrabhakar Kushwaha err = mc_apply_dpl(mc_dpl_addr); 1401b7b8410aSAlexander Graf } 1402fb4a87a7SPrabhakar Kushwaha break; 1403fb4a87a7SPrabhakar Kushwaha } 1404fb4a87a7SPrabhakar Kushwaha default: 1405fb4a87a7SPrabhakar Kushwaha printf("Invalid option: %s\n", argv[1]); 1406fb4a87a7SPrabhakar Kushwaha goto usage; 1407fb4a87a7SPrabhakar Kushwaha break; 1408fb4a87a7SPrabhakar Kushwaha } 1409fb4a87a7SPrabhakar Kushwaha return err; 1410fb4a87a7SPrabhakar Kushwaha usage: 1411fb4a87a7SPrabhakar Kushwaha return CMD_RET_USAGE; 1412fb4a87a7SPrabhakar Kushwaha } 1413fb4a87a7SPrabhakar Kushwaha 1414fb4a87a7SPrabhakar Kushwaha U_BOOT_CMD( 1415fb4a87a7SPrabhakar Kushwaha fsl_mc, CONFIG_SYS_MAXARGS, 1, do_fsl_mc, 1416fb4a87a7SPrabhakar Kushwaha "DPAA2 command to manage Management Complex (MC)", 1417fb4a87a7SPrabhakar Kushwaha "start mc [FW_addr] [DPC_addr] - Start Management Complex\n" 1418fb4a87a7SPrabhakar Kushwaha "fsl_mc apply DPL [DPL_addr] - Apply DPL file\n" 1419b7b8410aSAlexander Graf "fsl_mc lazyapply DPL [DPL_addr] - Apply DPL file on exit\n" 1420fb4a87a7SPrabhakar Kushwaha "fsl_mc start aiop [FW_addr] - Start AIOP\n" 1421fb4a87a7SPrabhakar Kushwaha ); 1422